@userdaoo/iflow-api-bridge 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -1,195 +1,168 @@
1
- # iFlow API Bridge
1
+ # @userdaoo/iflow-api-bridge
2
2
 
3
- 将 iFlow(心流)CLI 的无限 LLM 服务暴露为 OpenAI 兼容的 API,使 Claude Code、OpenCode 等 Agent 可以直接使用。
3
+ iFlow API 桥接服务 - 将 iFlow CLI 封装为 OpenAI 兼容的 API
4
4
 
5
5
  ## 特性
6
6
 
7
- - 🚀 **OpenAI API 兼容**:支持 `OPENAI_BASE_URL` 环境变量配置
8
- - 🔄 **流式输出**:完整的 SSE 流式响应支持
9
- - 🔌 **零配置**:自动检测和启动 iFlow 进程
10
- - 🌐 **CORS 支持**:开箱即用的跨域支持
11
- - 🔐 **可选认证**:支持 API Key 认证
12
- - 📦 **无状态**:不存储会话状态,每次请求独立处理
7
+ - OpenAI API 兼容 (`/v1/chat/completions`)
8
+ - 支持流式 (SSE) 和非流式响应
9
+ - 多模型支持 (GLM、DeepSeek、Kimi、Qwen、MiniMax 等)
10
+ - 上下文管理 - 超时后仍能保持对话连续性
11
+ - 支持自定义对话 ID 追踪会话
13
12
 
14
13
  ## 安装
15
14
 
16
15
  ```bash
17
- npm install -g @iflow-ai/iflow-api-bridge
16
+ npm install -g @userdaoo/iflow-api-bridge
18
17
  ```
19
18
 
20
- ## 快速开始
21
-
22
- ### 1. 启动服务
19
+ 或使用 npx:
23
20
 
24
21
  ```bash
25
- # 使用默认配置(端口 8080
26
- iflow-api-server
22
+ npx @userdaoo/iflow-api-bridge --port 8080
23
+ ```
27
24
 
28
- # 自定义端口
29
- iflow-api-server --port 3000
25
+ ## 使用方法
30
26
 
31
- # 指定模型(用于API标识,需在iFlow中预先配置)
32
- iflow-api-server --model claude
27
+ ### 1. 启动服务
33
28
 
34
- # 启用 API Key 认证
35
- iflow-api-server --api-key sk-your-secret-key
29
+ ```bash
30
+ # 使用默认模型 (GLM-4.7)
31
+ iflow-api-server --port 8080
32
+
33
+ # 指定模型
34
+ iflow-api-server --port 8080 --model kimi-k2.5
36
35
  ```
37
36
 
38
- ### 2. 在其他 Agent 中配置
37
+ ### 2. 配置客户端
38
+
39
+ **Claude Code / OpenCode:**
39
40
 
40
41
  ```bash
41
- # 设置环境变量
42
42
  export OPENAI_BASE_URL=http://localhost:8080/v1
43
- export OPENAI_API_KEY=sk-anything # 如果没有启用认证,可以填任意值
44
-
45
- # 启动 Claude Code
43
+ export OPENAI_API_KEY=sk-anything
46
44
  claude
47
-
48
- # 或使用 OpenCode
49
- opencode
50
45
  ```
51
46
 
52
- ## API 端点
53
-
54
- ### 聊天完成
47
+ ### 3. API 调用
55
48
 
56
49
  ```bash
50
+ # 非流式请求
57
51
  curl http://localhost:8080/v1/chat/completions \
58
52
  -H "Content-Type: application/json" \
59
- -H "Authorization: Bearer sk-anything" \
60
53
  -d '{
61
- "model": "iflow-default",
62
- "messages": [{"role": "user", "content": "Hello!"}],
63
- "stream": false
54
+ "model": "kimi-k2.5",
55
+ "messages": [{"role": "user", "content": "你好"}]
64
56
  }'
65
- ```
66
57
 
67
- ### 流式响应
68
-
69
- ```bash
58
+ # 流式请求
70
59
  curl http://localhost:8080/v1/chat/completions \
71
60
  -H "Content-Type: application/json" \
72
- -H "Authorization: Bearer sk-anything" \
73
61
  -d '{
74
- "model": "iflow-default",
75
- "messages": [{"role": "user", "content": "讲个故事"}],
76
- "stream": true
62
+ "model": "kimi-k2.5",
63
+ "stream": true,
64
+ "messages": [{"role": "user", "content": "你好"}]
77
65
  }'
78
66
  ```
79
67
 
80
- ### 模型列表
68
+ ## 支持的模型
69
+
70
+ 实际可用模型取决于你的 iFlow CLI 配置:
71
+
72
+ | 模型 ID | 名称 |
73
+ |---------|------|
74
+ | `glm-4.7` | GLM-4.7 (默认) |
75
+ | `iflow-rome-30ba3b` | iFlow-ROME-30BA3B (预览版) |
76
+ | `deepseek-v3.2` | DeepSeek-V3.2 |
77
+ | `glm-5` | GLM-5 |
78
+ | `qwen3-coder-plus` | Qwen3-Coder-Plus |
79
+ | `kimi-k2-thinking` | Kimi-K2-Thinking |
80
+ | `minimax-m2.5` | MiniMax-M2.5 |
81
+ | `kimi-k2.5` | Kimi-K2.5 |
82
+ | `kimi-k2-0905` | Kimi-K2-0905 |
83
+
84
+ 获取最新模型列表:
81
85
 
82
86
  ```bash
83
87
  curl http://localhost:8080/v1/models
84
88
  ```
85
89
 
86
- ### 健康检查
90
+ ## 上下文管理
91
+
92
+ 桥接器支持通过 HTTP Header `X-Conversation-Id` 追踪会话:
87
93
 
88
94
  ```bash
89
- curl http://localhost:8080/health
95
+ # 第一轮对话
96
+ curl http://localhost:8080/v1/chat/completions \
97
+ -H "Content-Type: application/json" \
98
+ -H "X-Conversation-Id: my-session-123" \
99
+ -d '{"messages": [{"role": "user", "content": "我叫 Alice"}]}'
100
+
101
+ # 第二轮对话(即使第一轮超时,仍能记住上下文)
102
+ curl http://localhost:8080/v1/chat/completions \
103
+ -H "Content-Type: application/json" \
104
+ -H "X-Conversation-Id: my-session-123" \
105
+ -d '{"messages": [{"role": "user", "content": "我叫什么名字?"}]}'
90
106
  ```
91
107
 
92
- ## CLI 选项
108
+ ### 上下文特性
93
109
 
94
- ```
95
- 选项:
96
- -p, --port <port> 服务端口 (默认: 8080)
97
- -h, --host <host> 服务主机 (默认: 0.0.0.0)
98
- --no-cors 禁用 CORS
99
- -k, --api-key <key> API Key 认证
100
- -m, --model <model> 指定使用的模型 (如 claude, gpt-4)
101
- -c, --config <path> 配置文件路径
102
- --log-level <level> 日志级别 (DEBUG|INFO|WARN|ERROR) (默认: INFO)
103
- -V, --version 显示版本号
104
- --help 显示帮助信息
105
- ```
110
+ - 每个会话独立保存历史消息
111
+ - 最多保留 20 条历史消息(可配置)
112
+ - 24 小时未访问的会话自动清理
113
+ - 超时后重试不会丢失上下文
114
+
115
+ ## API 端点
106
116
 
107
- ## 配置文件
117
+ | 端点 | 描述 |
118
+ |------|------|
119
+ | `GET /health` | 健康检查,返回会话统计 |
120
+ | `GET /v1/models` | 获取可用模型列表 |
121
+ | `POST /v1/chat/completions` | 聊天完成 |
108
122
 
109
- 创建 `iflow-api.config.json`:
123
+ ## 命令行选项
110
124
 
111
- ```json
112
- {
113
- "port": 8080,
114
- "host": "0.0.0.0",
115
- "cors": true,
116
- "apiKey": "sk-your-secret-key",
117
- "model": "claude",
118
- "logLevel": "INFO"
119
- }
120
125
  ```
126
+ Options:
127
+ -p, --port <port> 服务端口 (默认: 8080)
128
+ -h, --host <host> 服务主机 (默认: 0.0.0.0)
129
+ --no-cors 禁用 CORS
130
+ -k, --api-key <key> API Key 认证
131
+ -m, --model <model> 默认模型 (默认: glm-4.7)
132
+ -c, --config <path> 配置文件路径
133
+ --log-level <level> 日志级别 (DEBUG|INFO|WARN|ERROR)
134
+ --help 显示帮助
135
+ ```
136
+
137
+ ## 配置优先级
121
138
 
122
- 配置文件优先级(从高到低):
123
- 1. CLI 参数
139
+ 1. 命令行参数 (最高优先级)
124
140
  2. 环境变量
125
141
  3. 配置文件
126
142
  4. 默认值
127
143
 
128
144
  ## 环境变量
129
145
 
130
- | 变量名 | 说明 | 默认值 |
131
- |--------|------|--------|
132
- | `IFLOW_API_PORT` | 服务端口 | `8080` |
133
- | `IFLOW_API_HOST` | 服务主机 | `0.0.0.0` |
134
- | `IFLOW_API_KEY` | API Key | - |
135
- | `IFLOW_API_MODEL` | 指定模型名称 | - |
136
- | `IFLOW_API_LOG_LEVEL` | 日志级别 | `INFO` |
137
- | `IFLOW_API_CORS` | 启用 CORS | `true` |
138
-
139
- ## 模型配置
140
-
141
- **注意**:`--model` 参数(或 `IFLOW_API_MODEL` 环境变量)主要用于 API 响应标识,实际的模型选择需要在 iFlow CLI 中配置:
142
-
143
- 1. **启动桥接服务时指定模型名称**(用于 API 响应):
144
- ```bash
145
- iflow-api-server --model claude-3-opus
146
- ```
147
-
148
- 2. **在 iFlow CLI 中配置实际模型**:
149
- - 运行 `iflow` 进入交互界面
150
- - 使用 `/model` 或相关命令切换模型
151
- - 或使用 iFlow 的配置文件指定默认模型
152
-
153
- 3. **客户端请求时指定模型**:
154
- ```bash
155
- curl http://localhost:8080/v1/chat/completions \
156
- -H "Content-Type: application/json" \
157
- -d '{
158
- "model": "claude-3-opus",
159
- "messages": [{"role": "user", "content": "Hello!"}]
160
- }'
161
- ```
162
-
163
- 桥接服务会将模型信息传递给 iFlow,但实际使用的模型取决于 iFlow 的配置。
164
-
165
- ## 与 Claude Code 集成
166
-
167
- 1. 启动 iflow-api-server:
168
- ```bash
169
- iflow-api-server --port 8080
170
- ```
171
-
172
- 2. 配置 Claude Code:
173
- ```bash
174
- export OPENAI_BASE_URL=http://localhost:8080/v1
175
- export OPENAI_API_KEY=sk-iflow
176
- ```
177
-
178
- 3. 启动 Claude Code 并选择 OpenAI 模型:
179
- ```bash
180
- claude
181
- # 在 Claude Code 中选择使用 OpenAI 模型
182
- ```
183
-
184
- ## 架构
185
-
186
- ```
187
- ┌─────────────┐ HTTP/OpenAI API ┌─────────────┐ WebSocket ┌─────────┐
188
- │ Claude Code │ ─────────────────────────> │ iflow-api │ ──────────────────> │ iFlow │
189
- │ OpenCode │ │ -server │ │ CLI │
190
- └─────────────┘ └─────────────┘ └─────────┘
146
+ ```bash
147
+ export IFLOW_API_PORT=8080
148
+ export IFLOW_API_HOST=0.0.0.0
149
+ export IFLOW_API_KEY=your-secret-key
150
+ export IFLOW_MODEL=glm-4.7
151
+ export IFLOW_LOG_LEVEL=INFO
191
152
  ```
192
153
 
193
- ## 许可证
154
+ ## 注意事项
155
+
156
+ 1. **模型选择**: 实际可用模型取决于 iFlow CLI 的配置和 API key
157
+ 2. **超时设置**: 默认 5 分钟超时,防止长时间等待
158
+ 3. **上下文保持**: 即使客户端断开,服务端仍保留会话上下文
159
+ 4. **资源清理**: 定期清理 24 小时未使用的会话
160
+
161
+ ## 依赖
162
+
163
+ - Node.js >= 22
164
+ - iFlow CLI (必须已安装并可运行 `iflow` 命令)
165
+
166
+ ## License
194
167
 
195
- MIT
168
+ MIT
package/dist/adapter.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * iFlow SDK 适配器(使用子进程模式)
3
- * 封装与 iFlow CLI 的通信
3
+ * 封装与 iFlow CLI 的通信,支持对话上下文管理
4
4
  */
5
5
  export interface IFlowResponse {
6
6
  content: string;
@@ -22,38 +22,29 @@ export interface IFlowAdapterOptions {
22
22
  apiKey?: string;
23
23
  baseUrl?: string;
24
24
  timeout?: number;
25
+ maxHistoryLength?: number;
25
26
  }
26
- /**
27
- * iFlow 适配器 - 使用子进程模式
28
- */
29
27
  export declare class IFlowAdapter {
30
28
  private options;
31
29
  private defaultTimeout;
30
+ private conversations;
31
+ private readonly maxHistoryLength;
32
+ private cleanupInterval;
32
33
  constructor(options?: IFlowAdapterOptions);
33
- /**
34
- * 发送消息并获取完整响应(非流式)
35
- */
36
- sendMessage(prompt: string): Promise<IFlowResponse>;
37
- /**
38
- * 发送消息并获取流式响应
39
- */
40
- sendMessageStream(prompt: string): AsyncGenerator<StreamChunk>;
41
- /**
42
- * 解析 iFlow 输出,提取实际回复内容
43
- */
34
+ private getConversation;
35
+ private buildPromptWithHistory;
36
+ private saveMessage;
37
+ private cleanupExpiredConversations;
38
+ sendMessage(conversationId: string, systemMessage: string | undefined, userMessage: string): Promise<IFlowResponse>;
39
+ sendMessageStream(conversationId: string, systemMessage: string | undefined, userMessage: string): AsyncGenerator<StreamChunk>;
44
40
  private parseResponse;
45
- /**
46
- * 连接到 iFlow
47
- */
48
41
  connect(): Promise<void>;
49
- /**
50
- * 断开连接
51
- */
52
42
  disconnect(): void;
53
- /**
54
- * 检查是否已连接
55
- */
56
43
  isConnected(): boolean;
44
+ getStats(): {
45
+ conversationCount: number;
46
+ totalMessages: number;
47
+ };
57
48
  }
58
49
  export default IFlowAdapter;
59
50
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IACH,UAAU,EAAE,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC;CACjD;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,cAAc,CAAU;gBAEpB,OAAO,GAAE,mBAAwB;IAI7C;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAoDzD;;OAEG;IACI,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC;IA2ErE;;OAEG;IACH,OAAO,CAAC,aAAa;IAsBrB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,WAAW,IAAI,OAAO;CAIvB;AAED,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IACH,UAAU,EAAE,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC;CACjD;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAYD,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,eAAe,CAA+B;gBAE1C,OAAO,GAAE,mBAAwB;IAQ7C,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,sBAAsB;IAwB9B,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,2BAA2B;IAiB7B,WAAW,CACf,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,CAAC;IAyDlB,iBAAiB,CACtB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,WAAW,EAAE,MAAM,GAClB,cAAc,CAAC,WAAW,CAAC;IAkF9B,OAAO,CAAC,aAAa;IAoBf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,UAAU,IAAI,IAAI;IASlB,WAAW,IAAI,OAAO;IAItB,QAAQ,IAAI;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE;CAUjE;AAED,eAAe,YAAY,CAAC"}
package/dist/adapter.js CHANGED
@@ -1,31 +1,94 @@
1
1
  "use strict";
2
2
  /**
3
3
  * iFlow SDK 适配器(使用子进程模式)
4
- * 封装与 iFlow CLI 的通信
4
+ * 封装与 iFlow CLI 的通信,支持对话上下文管理
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.IFlowAdapter = void 0;
8
8
  const child_process_1 = require("child_process");
9
- /**
10
- * iFlow 适配器 - 使用子进程模式
11
- */
12
9
  class IFlowAdapter {
13
10
  options;
14
- defaultTimeout = 120000; // 2分钟默认超时
11
+ defaultTimeout = 300000;
12
+ conversations = new Map();
13
+ maxHistoryLength;
14
+ cleanupInterval = null;
15
15
  constructor(options = {}) {
16
16
  this.options = options;
17
+ this.maxHistoryLength = options.maxHistoryLength || 20;
18
+ this.cleanupInterval = setInterval(() => {
19
+ this.cleanupExpiredConversations();
20
+ }, 30 * 60 * 1000);
21
+ }
22
+ getConversation(conversationId) {
23
+ let conversation = this.conversations.get(conversationId);
24
+ if (!conversation) {
25
+ conversation = {
26
+ messages: [],
27
+ lastAccessTime: Date.now(),
28
+ };
29
+ this.conversations.set(conversationId, conversation);
30
+ }
31
+ else {
32
+ conversation.lastAccessTime = Date.now();
33
+ }
34
+ return conversation;
35
+ }
36
+ buildPromptWithHistory(conversationId, systemMessage, userMessage) {
37
+ const conversation = this.getConversation(conversationId);
38
+ const parts = [];
39
+ if (systemMessage) {
40
+ parts.push(`System: ${systemMessage}`);
41
+ }
42
+ for (const msg of conversation.messages) {
43
+ if (msg.role === 'user') {
44
+ parts.push(`User: ${msg.content}`);
45
+ }
46
+ else if (msg.role === 'assistant') {
47
+ parts.push(`Assistant: ${msg.content}`);
48
+ }
49
+ }
50
+ parts.push(`User: ${userMessage}`);
51
+ return parts.join('\n\n');
52
+ }
53
+ saveMessage(conversationId, role, content) {
54
+ const conversation = this.getConversation(conversationId);
55
+ conversation.messages.push({ role, content });
56
+ if (conversation.messages.length > this.maxHistoryLength) {
57
+ const systemMessages = conversation.messages.filter(m => m.role === 'system');
58
+ const otherMessages = conversation.messages.filter(m => m.role !== 'system');
59
+ const keepCount = this.maxHistoryLength - systemMessages.length;
60
+ conversation.messages = [
61
+ ...systemMessages,
62
+ ...otherMessages.slice(-keepCount),
63
+ ];
64
+ }
65
+ conversation.lastAccessTime = Date.now();
66
+ }
67
+ cleanupExpiredConversations() {
68
+ const now = Date.now();
69
+ const expireTime = 24 * 60 * 60 * 1000;
70
+ let cleaned = 0;
71
+ for (const [id, conversation] of this.conversations.entries()) {
72
+ if (now - conversation.lastAccessTime > expireTime) {
73
+ this.conversations.delete(id);
74
+ cleaned++;
75
+ }
76
+ }
77
+ if (cleaned > 0) {
78
+ console.log(`[Adapter] 清理了 ${cleaned} 个过期会话`);
79
+ }
17
80
  }
18
- /**
19
- * 发送消息并获取完整响应(非流式)
20
- */
21
- async sendMessage(prompt) {
22
- console.log('[Adapter] 发送消息(非流式):', prompt.substring(0, 100));
81
+ async sendMessage(conversationId, systemMessage, userMessage) {
82
+ const prompt = this.buildPromptWithHistory(conversationId, systemMessage, userMessage);
83
+ console.log(`[Adapter] 发送消息(非流式)会话: ${conversationId}`);
84
+ console.log(`[Adapter] 历史消息数: ${this.getConversation(conversationId).messages.length}`);
85
+ this.saveMessage(conversationId, 'user', userMessage);
23
86
  return new Promise((resolve, reject) => {
24
87
  const args = ['-p', prompt];
25
88
  if (this.options.model) {
26
89
  args.push('-m', this.options.model);
27
90
  }
28
- console.log('[Adapter] 启动 iflow:', args.join(' '));
91
+ console.log('[Adapter] 启动 iflow:', args.slice(0, 3).join(' ') + '...');
29
92
  const child = (0, child_process_1.spawn)('iflow', args, {
30
93
  stdio: ['ignore', 'pipe', 'pipe'],
31
94
  });
@@ -49,10 +112,10 @@ class IFlowAdapter {
49
112
  clearTimeout(timeout);
50
113
  console.log('[Adapter] iFlow 退出,code:', code);
51
114
  if (code !== 0 && code !== null) {
52
- console.error('[Adapter] iFlow stderr:', stderr);
115
+ console.error('[Adapter] iFlow stderr:', stderr.substring(0, 500));
53
116
  }
54
- // 解析响应
55
117
  const content = this.parseResponse(stdout);
118
+ this.saveMessage(conversationId, 'assistant', content);
56
119
  resolve({
57
120
  content,
58
121
  stopReason: code === 0 ? 'end_turn' : 'error',
@@ -60,21 +123,22 @@ class IFlowAdapter {
60
123
  });
61
124
  });
62
125
  }
63
- /**
64
- * 发送消息并获取流式响应
65
- */
66
- async *sendMessageStream(prompt) {
67
- console.log('[Adapter] 发送消息(流式):', prompt.substring(0, 100));
126
+ async *sendMessageStream(conversationId, systemMessage, userMessage) {
127
+ const prompt = this.buildPromptWithHistory(conversationId, systemMessage, userMessage);
128
+ console.log(`[Adapter] 发送消息(流式)会话: ${conversationId}`);
129
+ console.log(`[Adapter] 历史消息数: ${this.getConversation(conversationId).messages.length}`);
130
+ this.saveMessage(conversationId, 'user', userMessage);
68
131
  const args = ['-p', prompt];
69
132
  if (this.options.model) {
70
133
  args.push('-m', this.options.model);
71
134
  }
72
- console.log('[Adapter] 启动 iflow:', args.join(' '));
135
+ console.log('[Adapter] 启动 iflow:', args.slice(0, 3).join(' ') + '...');
73
136
  const child = (0, child_process_1.spawn)('iflow', args, {
74
137
  stdio: ['ignore', 'pipe', 'pipe'],
75
138
  });
76
139
  let buffer = '';
77
140
  let isDone = false;
141
+ let fullContent = '';
78
142
  const timeout = setTimeout(() => {
79
143
  if (!isDone) {
80
144
  child.kill('SIGTERM');
@@ -87,20 +151,17 @@ class IFlowAdapter {
87
151
  });
88
152
  child.stderr?.on('data', (data) => {
89
153
  const msg = data.toString();
90
- console.log('[Adapter] iFlow stderr:', msg.trim());
154
+ console.log('[Adapter] iFlow stderr:', msg.trim().substring(0, 200));
91
155
  });
92
- // 模拟流式输出 - 逐字符发送
93
156
  let lastSentIndex = 0;
94
157
  while (!isDone) {
95
- // 检查进程是否结束
96
158
  if (child.exitCode !== null) {
97
159
  isDone = true;
98
160
  }
99
- // 发送新内容
100
161
  if (buffer.length > lastSentIndex) {
101
162
  const newContent = buffer.slice(lastSentIndex);
102
163
  lastSentIndex = buffer.length;
103
- // 逐行或逐字符发送
164
+ fullContent += newContent;
104
165
  const lines = newContent.split('\n');
105
166
  for (const line of lines) {
106
167
  if (line.trim()) {
@@ -116,25 +177,23 @@ class IFlowAdapter {
116
177
  }
117
178
  }
118
179
  clearTimeout(timeout);
119
- // 发送剩余内容
120
180
  if (buffer.length > lastSentIndex) {
181
+ const remaining = buffer.slice(lastSentIndex);
182
+ fullContent += remaining;
121
183
  yield {
122
184
  type: 'content',
123
- content: buffer.slice(lastSentIndex),
185
+ content: remaining,
124
186
  };
125
187
  }
188
+ const finalContent = this.parseResponse(fullContent);
189
+ this.saveMessage(conversationId, 'assistant', finalContent);
126
190
  yield { type: 'done' };
127
191
  }
128
- /**
129
- * 解析 iFlow 输出,提取实际回复内容
130
- */
131
192
  parseResponse(stdout) {
132
- // 尝试提取 <Execution Info> 之前的内容作为回复
133
193
  const executionInfoMatch = stdout.match(/<Execution Info>[\s\S]*$/);
134
194
  if (executionInfoMatch) {
135
195
  return stdout.substring(0, executionInfoMatch.index).trim();
136
196
  }
137
- // 如果没有 Execution Info,返回全部内容(去掉开头的警告)
138
197
  const lines = stdout.split('\n');
139
198
  const startIndex = lines.findIndex((line) => !line.includes('DeprecationWarning') &&
140
199
  !line.includes('node:') &&
@@ -144,27 +203,30 @@ class IFlowAdapter {
144
203
  }
145
204
  return stdout.trim();
146
205
  }
147
- /**
148
- * 连接到 iFlow
149
- */
150
206
  async connect() {
151
- // 子进程模式不需要持久连接
152
- console.log('[Adapter] 子进程模式已就绪');
207
+ console.log('[Adapter] 子进程模式已就绪,支持上下文管理');
153
208
  }
154
- /**
155
- * 断开连接
156
- */
157
209
  disconnect() {
158
- // 子进程模式不需要断开连接
159
- console.log('[Adapter] 子进程模式断开(无操作)');
210
+ console.log('[Adapter] 子进程模式断开,清理资源...');
211
+ if (this.cleanupInterval) {
212
+ clearInterval(this.cleanupInterval);
213
+ this.cleanupInterval = null;
214
+ }
215
+ this.conversations.clear();
160
216
  }
161
- /**
162
- * 检查是否已连接
163
- */
164
217
  isConnected() {
165
- // 子进程模式总是"已连接"
166
218
  return true;
167
219
  }
220
+ getStats() {
221
+ let totalMessages = 0;
222
+ for (const conv of this.conversations.values()) {
223
+ totalMessages += conv.messages.length;
224
+ }
225
+ return {
226
+ conversationCount: this.conversations.size,
227
+ totalMessages,
228
+ };
229
+ }
168
230
  }
169
231
  exports.IFlowAdapter = IFlowAdapter;
170
232
  exports.default = IFlowAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}