@iflow-ai/iflow-cli-sdk 0.1.9 → 0.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,20 @@
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.2.0-beta.0] - 2026-01-27
11
+
12
+ ### 新增能力
13
+ - 配置选项支持 `stream` 参数控制流式输出(依赖 iFlow CLI v0.5.2+)
14
+ - 新增 `setThink()` 方法,支持配置思考模式
15
+ - 新增 `connect()` 时,支持加载已有会话
16
+ - 新增用户交互方法:
17
+ - `respondToAskUserQuestions()` - 响应 AI 问题请求
18
+ - `respondToExitPlanMode()` - 响应计划审批请求
19
+ - 新增工具权限请求处理,支持 `respondToPermissionRequest()` 和 `rejectPermissionRequest()` 方法
20
+ - `sendMessage()` 支持图像和文本选择等多种文件类型
21
+
22
+ ---
23
+
10
24
  ## [0.1.9] - 2026-01-26
11
25
 
12
26
  ### 优化
package/README.md CHANGED
@@ -14,18 +14,12 @@ A powerful TypeScript SDK for interacting with iFlow CLI using the Agent Communi
14
14
  - 🚀 **Automatic Process Management** - Zero-config setup! SDK auto-starts and manages iFlow CLI
15
15
  - 🔌 **Smart Port Detection** - Automatically finds available ports, no conflicts
16
16
  - 🔄 **Bidirectional Communication** - Real-time streaming of messages and responses
17
- - 🛠️ **Tool Call Management** - Handle and control tool executions with fine-grained permissions
18
- - 🤖 **SubAgent Support** - Track and manage multiple AI agents with `agentId` propagation
19
- - 📋 **Task Planning** - Receive and process structured task plans
20
- - 🔍 **Raw Data Access** - Debug and inspect protocol-level messages
21
- - ⚡ **Async/Await Support** - Modern asynchronous Python with full type hints
17
+ - 🛠️ **Tool Call Management** - Handle and control tool executions
18
+ - 🔐 **Permission Request Handling** - Manage and respond to tool execution permission requests
19
+ - 💬 **Interactive Questions** - AI can ask users questions during execution
20
+ - 📝 **Plan Approval** - Review and approve AI plans before execution
21
+ - ⚡ **Async/Await Support** - Modern asynchronous TypeScript with full type hints
22
22
  - 🎯 **Simple & Advanced APIs** - From one-line queries to complex conversation management
23
- - 📦 **Full ACP v1 Protocol** - Complete implementation of the Agent Communication Protocol
24
- - 🚦 **Advanced Approval Modes** - Including `default`, `autoEdit`, `yolo`, and `plan` modes
25
- - 🔗 **MCP Server Integration** - Support for Model Context Protocol servers
26
- - 🪝 **Lifecycle Hooks** - Execute commands at different stages of conversation
27
- - 🎮 **Session Settings** - Fine-grained control over model behavior and tools
28
- - 🤖 **Custom Agents** - Define specialized agents with custom prompts and tools
29
23
 
30
24
  ## Installation
31
25
 
@@ -57,8 +51,6 @@ npm install --save @iflow-ai/iflow-cli-sdk
57
51
 
58
52
  The SDK **automatically manages the iFlow process** - no manual setup required!
59
53
 
60
- ### Default Usage (Automatic Process Management)
61
-
62
54
  ```ts
63
55
  import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
64
56
 
@@ -73,256 +65,316 @@ async function main() {
73
65
  await client.connect();
74
66
  await client.sendMessage("Hello, iFlow!");
75
67
 
76
- for await (const message in client.receiveMessages()) {
68
+ for await (const message of client.receiveMessages()) {
77
69
  console.log(message);
78
70
  // Process messages...
79
71
  }
72
+
73
+ await client.disconnect();
80
74
  }
81
75
  ```
82
76
 
83
77
  **No need to manually start iFlow!** The SDK handles everything for you.
84
78
 
85
- ### Advanced: Manual Process Control
79
+ ## Examples
86
80
 
87
- If you need to manage iFlow yourself (rare cases):
81
+ ### Simple Query
88
82
 
89
- ```ts
90
- import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
83
+ Use the convenience function for one-off queries:
91
84
 
92
- async function main() {
93
- // Disable automatic process management
94
- const client = new IFlowClient({
95
- url: "ws://localhost:8090/acp", // Connect to existing iFlow
96
- autoStartProcess: false,
97
- });
85
+ ```ts
86
+ import { query } from "@iflow-ai/iflow-cli-sdk";
98
87
 
99
- await client.connect();
100
- await client.sendMessage("Hello, iFlow!");
101
- }
88
+ const response = await query("What is the capital of France?");
89
+ console.log(response);
102
90
  ```
103
91
 
104
- **Note:** Manual mode requires you to start iFlow separately:
92
+ ### Interactive Conversation
105
93
 
106
- ```bash
107
- iflow --experimental-acp --port 8090
108
- ```
94
+ For more control over the conversation:
109
95
 
110
- ### Simple Examples
96
+ ```ts
97
+ import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
111
98
 
112
- #### Simple Query
99
+ const client = new IFlowClient();
113
100
 
114
- ```ts
115
- import { query } from "@iflow-ai/iflow-cli-sdk";
101
+ await client.connect();
102
+ await client.sendMessage("Explain quantum computing");
116
103
 
117
- async function main() {
118
- const response = await query("What is the capital of France?");
119
- console.log(response); // "The capital of France is Paris."
104
+ for await (const message of client.receiveMessages()) {
105
+ if (message.type === "assistant" && message.chunk.text) {
106
+ console.log(message.chunk.text);
107
+ } else if (message.type === "task_finish") {
108
+ break;
109
+ }
120
110
  }
111
+
112
+ await client.disconnect();
121
113
  ```
122
114
 
123
- #### Interactive Conversation
115
+ ### Tool Call Monitoring
116
+
117
+ Monitor tool executions:
124
118
 
125
119
  ```ts
126
- import { IFlowClient, MessageType } from "@iflow-ai/iflow-cli-sdk";
120
+ import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
127
121
 
128
- async function main() {
129
- const client = new IFlowClient();
122
+ const client = new IFlowClient({ permissionMode: "auto" });
130
123
 
131
- await client.connect();
132
- await client.sendMessage("Explain quantum computing");
124
+ await client.connect();
125
+ await client.sendMessage("Create a file called test.txt");
133
126
 
134
- for await (const message in client.receiveMessages()) {
135
- if (message.type === MessageType.ASSISTANT && message.chunk.text) {
136
- console.log(message.chunk.text);
137
- } else if (message.type === MessageType.TASK_FINISH) {
138
- break;
127
+ for await (const message of client.receiveMessages()) {
128
+ if (message.type === "tool_call") {
129
+ console.log(`Tool: ${message.toolName}, Status: ${message.status}`);
130
+ if (message.output) {
131
+ console.log(`Output: ${message.output}`);
139
132
  }
133
+ } else if (message.type === "task_finish") {
134
+ break;
140
135
  }
141
136
  }
137
+
138
+ await client.disconnect();
142
139
  ```
143
140
 
144
- #### Tool Call Control with Agent Information
141
+ ### Enhanced File Types
142
+
143
+ The SDK supports multiple file types beyond simple file paths:
145
144
 
146
145
  ```ts
147
- import { IFlowClient, PermissionMode, MessageType } from "@iflow-ai/iflow-cli-sdk";
146
+ import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
148
147
 
149
- async function main() {
150
- const client = new IFlowClient({
151
- permissionMode: PermissionMode.AUTO,
152
- })
148
+ const client = new IFlowClient();
149
+ await client.connect();
153
150
 
154
- await client.connect();
155
- await client.sendMessage("Create a file called test.txt");
156
-
157
- for await (const message in client.receiveMessages()) {
158
- if (message.type === MessageType.TOOL_CALL) {
159
- console.log(`Tool name: ${message.toolName}`);
160
- console.log(`Tool status: ${message.status}`);
161
-
162
- if (message.agentInfo) {
163
- console.log(`Agent ID: ${message.agentInfo.agentId}`);
164
- console.log(`Task ID: ${message.agentInfo.taskId}`);
165
- console.log(`Agent index: ${message.agentInfo.agentIndex}`);
166
- }
167
-
168
- if (message.args) {
169
- console.log(message.args);
170
- }
171
- if (message.output) {
172
- console.log(message.output);
173
- }
174
- } else if (message.type === MessageType.TASK_FINISH) {
175
- break;
176
- }
151
+ // 1. Use image data
152
+ const image = {
153
+ type: "image" as const,
154
+ data: "base64-encoded-image-data",
155
+ mimeType: "image/png"
156
+ };
157
+ await client.sendMessage("Analyze this image", [image]);
158
+
159
+ // 2. Use text selection
160
+ const selection = {
161
+ type: "selection" as const,
162
+ data: "const sum = (a, b) => a + b;",
163
+ uri: "file:///path/to/file.ts",
164
+ line: { start: 1, end: 2 }
165
+ };
166
+ await client.sendMessage("Explain this code", [selection]);
167
+
168
+ // 3. Mix different file types
169
+ await client.sendMessage("Analyze these files", [
170
+ "package.json", // File path
171
+ image, // Image data
172
+ selection // Text selection
173
+ ]);
174
+
175
+ await client.disconnect();
176
+ ```
177
+
178
+ ### Interactive Questions
179
+
180
+ Handle AI questions during execution:
181
+
182
+ ```ts
183
+ import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
184
+
185
+ const client = new IFlowClient();
186
+ await client.connect();
187
+ await client.sendMessage("Help me create a web server");
188
+
189
+ for await (const message of client.receiveMessages()) {
190
+ if (message.type === "ask_user_questions") {
191
+ // Display questions
192
+ message.questions.forEach(q => {
193
+ console.log(`${q.question}`);
194
+ q.options.forEach(opt => console.log(`- ${opt.label}`));
195
+ });
196
+
197
+ // Collect and send answers
198
+ const answers = {
199
+ [message.questions[0].header]: message.questions[0].options[0].label
200
+ };
201
+ await client.respondToAskUserQuestions(answers);
202
+ } else if (message.type === "task_finish") {
203
+ break;
177
204
  }
178
205
  }
206
+
207
+ await client.disconnect();
179
208
  ```
180
209
 
181
- #### Working with AgentInfo
210
+ ### Plan Approval
211
+
212
+ Review and approve AI plans:
182
213
 
183
214
  ```ts
184
- import { IFlowClient, MessageType } from "@iflow-ai/iflow-cli-sdk";
185
-
186
- const options: IFlowOptions = {
187
- agents: [
188
- {
189
- agentType: "code-reviewer",
190
- name: "reviewer",
191
- description: "Code review specialist",
192
- whenToUse: "For code review and quality checks",
193
- allowedTools: ["fs", "grep"],
194
- allowedMcps: ["eslint", "prettier"],
195
- systemPrompt: "You are a code review expert.",
196
- proactive: False,
197
- location: "project",
198
- },
199
- {
200
- agentType: "test-writer",
201
- name: "tester",
202
- description: "Test writing specialist",
203
- whenToUse: "For writing unit and integration tests",
204
- allowedTools: ["fs", "bash"],
205
- systemPrompt: "You are a test writing expert.",
206
- location: "project",
207
- },
208
- ],
209
- };
215
+ import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
210
216
 
211
- async function main() {
212
- const client = new IFlowClient(options)
217
+ const client = new IFlowClient();
218
+ await client.connect();
219
+ await client.sendMessage("Refactor the authentication module");
220
+
221
+ for await (const message of client.receiveMessages()) {
222
+ if (message.type === "exit_plan_mode") {
223
+ console.log("AI Plan:", message.plan);
224
+
225
+ // Approve or reject the plan
226
+ const approved = true;
227
+ await client.respondToExitPlanMode(approved);
228
+ } else if (message.type === "task_finish") {
229
+ break;
230
+ }
231
+ }
213
232
 
214
- await client.connect();
215
- await client.sendMessage("$test-writer Write a unit test");
216
-
217
- for await (const message in client.receiveMessages()) {
218
- if (message.type === MessageType.TOOL_CALL) {
219
- console.log(`Tool name: ${message.toolName}`);
220
-
221
- if (message.args) {
222
- console.log(message.args);
223
- }
224
- if (message.output) {
225
- console.log(message.output);
226
- }
227
- } if (message.type === MessageType.ASSISTANT && message.chunk.text) {
228
- console.log(message.chunk.text);
229
- } else if (message.type === MessageType.TASK_FINISH) {
230
- break;
233
+ await client.disconnect();
234
+ ```
235
+
236
+ ### Permission Request Handling
237
+
238
+ Handle tool execution permission requests from AI:
239
+
240
+ ```ts
241
+ import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
242
+
243
+ const client = new IFlowClient();
244
+ await client.connect();
245
+ await client.sendMessage("Create a file and write some code");
246
+
247
+ for await (const message of client.receiveMessages()) {
248
+ if (message.type === "permission_request") {
249
+ console.log(`Tool permission request: ${message.toolCall.title}`);
250
+ console.log(`Request ID: ${message.requestId}`);
251
+
252
+ // Display available options
253
+ console.log("Available options:");
254
+ message.options.forEach(option => {
255
+ console.log(`- ${option.optionId}`);
256
+ });
257
+
258
+ // Based on user input, either approve or cancel
259
+ const userChoice = "proceed_once"; // or based on user input
260
+
261
+ if (userChoice === "cancel") {
262
+ await client.cancelToolConfirmation(message.requestId);
263
+ console.log("Permission request cancelled");
264
+ } else {
265
+ await client.respondToToolConfirmation(message.requestId, userChoice);
266
+ console.log(`Permission approved with option: ${userChoice}`);
231
267
  }
268
+ } else if (message.type === "task_finish") {
269
+ break;
232
270
  }
233
271
  }
272
+
273
+ await client.disconnect();
234
274
  ```
235
275
 
236
- #### Advanced Protocol Features
276
+ ### Configuration Management
277
+
278
+ Manage session configuration for models and modes:
237
279
 
238
280
  ```ts
239
- import { IFlowClient, IFlowOptions, ApprovalMode, HookEventType } from "@iflow-ai/iflow-cli-sdk";
240
-
241
- const options: IFlowOptions = {
242
- mcpServers: [
243
- {
244
- name: "filesystem",
245
- command: "mcp-server-filesystem",
246
- args: ["--allowed-dirs", "/workspace"],
247
- env: [
248
- {
249
- name: "DEBUG",
250
- value: "1",
251
- },
252
- ],
253
- },
254
- ],
255
-
256
- sessionSettings: {
257
- allowed_tools: ["read_file", "write_file", "execute_code"],
258
- system_prompt: "You are an expert Python developer",
259
- permission_mode: ApprovalMode.AUTO_EDIT,
260
- max_turns: 100,
261
- },
262
-
263
- hooks: {
264
- [HookEventType.PRE_TOOL_USE]: [
265
- {
266
- hooks: {
267
- command: "echo 'Processing request...'",
268
- timeout: 5,
269
- },
270
- },
271
- ],
272
- },
273
-
274
- commands: [
275
- {
276
- name: "test",
277
- content: "pytest --verbose",
278
- },
279
- ],
280
-
281
- agents: [
282
- {
283
- agentType: "python-expert",
284
- whenToUse: "For Python development tasks",
285
- allowedTools: ["edit_file", "run_python", "debug"],
286
- systemPrompt: "You are a Python expert focused on clean, efficient code",
287
- name: "Python Expert",
288
- description: "Specialized in Python development",
289
- },
290
- ],
291
- };
281
+ import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
292
282
 
293
- async function main() {
294
- const client = new IFlowClient(options);
283
+ const client = new IFlowClient();
284
+ await client.connect();
295
285
 
296
- await client.connect();
297
- await client.sendMessage("$test-writer Write a unit test");
286
+ // Get available models and modes
287
+ const models = await client.config.get("models");
288
+ const modes = await client.config.get("modes");
298
289
 
299
- // Process responses...
300
- }
290
+ console.log("Available models:", models);
291
+ console.log("Available modes:", modes);
292
+
293
+ // Get current configuration
294
+ const currentModel = await client.config.get("model");
295
+ const currentMode = await client.config.get("mode");
296
+
297
+ console.log("Current model:", currentModel);
298
+ console.log("Current mode:", currentMode);
299
+
300
+ // Set new configuration
301
+ await client.config.set("model", "glm-4.7");
302
+ await client.config.set("mode", "plan");
303
+
304
+ console.log("Switched to glm-4.7 model and plan mode");
305
+
306
+ await client.disconnect();
301
307
  ```
302
308
 
303
- ## API Reference
309
+ ### Complete Configuration Example
310
+
311
+ ```ts
312
+ import { IFlowClient } from "@iflow-ai/iflow-cli-sdk";
304
313
 
305
- ### Core Classes
314
+ async function configExample() {
315
+ const client = new IFlowClient();
316
+
317
+ try {
318
+ await client.connect();
319
+
320
+ // Get all available configuration
321
+ const models = await client.config.get("models");
322
+ const modes = await client.config.get("modes");
323
+ const commands = await client.config.get("commands");
324
+ const agents = await client.config.get("agents");
325
+ const skills = await client.config.get("skills");
326
+ const mcpServers = await client.config.get("mcpServers");
327
+
328
+ console.log("=== Configuration Information ===");
329
+ console.log("Available models:", models);
330
+ console.log("Available modes:", modes);
331
+ console.log("Available commands:", commands);
332
+ console.log("Available agents:", agents);
333
+ console.log("Available skills:", skills);
334
+ console.log("Available MCP servers:", mcpServers);
335
+
336
+ // Save original configuration
337
+ const originalModel = await client.config.get("model");
338
+ const originalMode = await client.config.get("mode");
339
+
340
+ // Temporarily switch configuration
341
+ await client.config.set("model", "glm-4.7");
342
+ await client.config.set("mode", "plan");
343
+
344
+ console.log("Switched to glm-4.7 model and plan mode");
345
+
346
+ // Restore original configuration
347
+ await client.config.set("model", originalModel);
348
+ await client.config.set("mode", originalMode);
349
+
350
+ console.log("Restored original configuration");
351
+
352
+ } finally {
353
+ await client.disconnect();
354
+ }
355
+ }
306
356
 
307
- - **`IFlowClient`**: Main client for bidirectional communication
308
- - **`IFlowOptions`**: Configuration options
309
- - **`RawDataClient`**: Access to raw protocol data
357
+ configExample().catch(console.error);
358
+ ```
310
359
 
311
- ### Message Types
360
+ ## API Reference
312
361
 
313
- - **`AssistantMessage`**: AI assistant responses with optional agent information
314
- - **`ToolCallMessage`**: Tool execution requests with execution details (toolName, args, output) and agent information
315
- - **`PlanMessage`**: Structured task plans with priority and status
316
- - **`TaskFinishMessage`**: Task completion signal with stop reason (end_urn, max_tokens, refusal, cancelled)
362
+ 详细的 API 文档请查看 [API_REFERENCE.md](API_REFERENCE.md)
317
363
 
318
- ### Agent Information
364
+ ### 核心类
319
365
 
320
- - **`AgentInfo`**: Agent metadata extracted from iFlow's agentId format (agentId, taskId, agentIndex, timestamp)
366
+ - **`IFlowClient`** - 主要客户端类
367
+ - **`query()`** / **`queryStream()`** - 便捷查询函数
321
368
 
322
- ### Convenience Functions
369
+ ### 主要消息类型
323
370
 
324
- - `query(prompt)`: Simple synchronous query
325
- - `queryStream(prompt)`: Streaming responses
371
+ - `AssistantMessage` - AI 响应
372
+ - `ToolCallMessage` - 工具调用
373
+ - `TaskFinishMessage` - 任务完成
374
+ - `AskUserQuestionsMessage` - 用户问题
375
+ - `ExitPlanModeMessage` - 计划审批
376
+ - `PermissionRequestMessage` - 权限请求
377
+ - `ErrorMessage` - 错误消息
326
378
 
327
379
  ## Project Structure
328
380
 
@@ -348,12 +400,19 @@ src/
348
400
 
349
401
  ## Development
350
402
 
403
+ ### Build dev package
404
+ ```bash
405
+ npm run dev
406
+ ```
407
+
351
408
  ### Running Tests
352
409
 
353
410
  ```bash
354
411
  npm test
355
412
  ```
356
413
 
414
+ > 💡 **Testing Tool**: See [`mock-server/`](./mock-server/) directory for the ACP Mock Server, useful for testing and development without a real CLI.
415
+
357
416
  ### Code Quality
358
417
 
359
418
  ```bash
@@ -366,26 +425,12 @@ npm run format
366
425
 
367
426
  ## Protocol Support
368
427
 
369
- The SDK implements the Agent Communication Protocol (ACP) v1 with full extension support, including:
370
-
371
- - **Session Management**: Create, load, and manage conversation sessions with advanced settings
372
- - **Message Types**:
373
- - `agent_message_chunk` - Assistant responses
374
- - `agent_thought_chunk` - Internal reasoning
375
- - `tool_call` / `tool_call_update` - Tool execution lifecycle
376
- - `plan` - Structured task planning with priorities
377
- - `user_message_chunk` - User message echoing
378
- - `stop_reason` - Task completion with reason (end_turn, max_tokens, refusal, cancelled)
379
- - **Authentication**: Built-in iFlow authentication with token support
380
- - **File System Access**: Read/write file permissions with configurable limits
381
- - **SubAgent Support**: Full `agentId` tracking and management
382
- - **Advanced Features**:
383
- - **MCP Servers**: Integrate Model Context Protocol servers for extended capabilities
384
- - **Approval Modes**: DEFAULT, AUTO_EDIT, YOLO (auto-approve all), PLAN modes
385
- - **Session Settings**: Control allowed tools, system prompts, model selection
386
- - **Lifecycle Hooks**: Execute commands at different conversation stages
387
- - **Custom Commands**: Define and execute custom commands
388
- - **Specialized Agents**: Create agents with specific expertise and tool access
428
+ SDK 完整实现了 Agent Communication Protocol (ACP) v1,支持:
429
+
430
+ - 会话管理和消息流式传输
431
+ - 工具调用和权限控制
432
+ - 用户交互(提问和计划审批)
433
+ - 完整的错误处理
389
434
 
390
435
  ## Contributing
391
436