@userdaoo/iflow-api-bridge 0.1.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/README.md +195 -0
- package/dist/adapter.d.ts +59 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +171 -0
- package/dist/adapter.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +57 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +83 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/openai/transformer.d.ts +52 -0
- package/dist/openai/transformer.d.ts.map +1 -0
- package/dist/openai/transformer.js +120 -0
- package/dist/openai/transformer.js.map +1 -0
- package/dist/openai/types.d.ts +96 -0
- package/dist/openai/types.d.ts.map +1 -0
- package/dist/openai/types.js +6 -0
- package/dist/openai/types.js.map +1 -0
- package/dist/server.d.ts +49 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +278 -0
- package/dist/server.js.map +1 -0
- package/iflow-api.config.example.json +8 -0
- package/package.json +43 -0
- package/src/adapter.ts +227 -0
- package/src/cli.ts +64 -0
- package/src/config.ts +102 -0
- package/src/index.ts +27 -0
- package/src/openai/transformer.ts +142 -0
- package/src/openai/types.ts +102 -0
- package/src/server.ts +341 -0
- package/tsconfig.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# iFlow API Bridge
|
|
2
|
+
|
|
3
|
+
将 iFlow(心流)CLI 的无限 LLM 服务暴露为 OpenAI 兼容的 API,使 Claude Code、OpenCode 等 Agent 可以直接使用。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🚀 **OpenAI API 兼容**:支持 `OPENAI_BASE_URL` 环境变量配置
|
|
8
|
+
- 🔄 **流式输出**:完整的 SSE 流式响应支持
|
|
9
|
+
- 🔌 **零配置**:自动检测和启动 iFlow 进程
|
|
10
|
+
- 🌐 **CORS 支持**:开箱即用的跨域支持
|
|
11
|
+
- 🔐 **可选认证**:支持 API Key 认证
|
|
12
|
+
- 📦 **无状态**:不存储会话状态,每次请求独立处理
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g @iflow-ai/iflow-api-bridge
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 快速开始
|
|
21
|
+
|
|
22
|
+
### 1. 启动服务
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# 使用默认配置(端口 8080)
|
|
26
|
+
iflow-api-server
|
|
27
|
+
|
|
28
|
+
# 自定义端口
|
|
29
|
+
iflow-api-server --port 3000
|
|
30
|
+
|
|
31
|
+
# 指定模型(用于API标识,需在iFlow中预先配置)
|
|
32
|
+
iflow-api-server --model claude
|
|
33
|
+
|
|
34
|
+
# 启用 API Key 认证
|
|
35
|
+
iflow-api-server --api-key sk-your-secret-key
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. 在其他 Agent 中配置
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# 设置环境变量
|
|
42
|
+
export OPENAI_BASE_URL=http://localhost:8080/v1
|
|
43
|
+
export OPENAI_API_KEY=sk-anything # 如果没有启用认证,可以填任意值
|
|
44
|
+
|
|
45
|
+
# 启动 Claude Code
|
|
46
|
+
claude
|
|
47
|
+
|
|
48
|
+
# 或使用 OpenCode
|
|
49
|
+
opencode
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## API 端点
|
|
53
|
+
|
|
54
|
+
### 聊天完成
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
curl http://localhost:8080/v1/chat/completions \
|
|
58
|
+
-H "Content-Type: application/json" \
|
|
59
|
+
-H "Authorization: Bearer sk-anything" \
|
|
60
|
+
-d '{
|
|
61
|
+
"model": "iflow-default",
|
|
62
|
+
"messages": [{"role": "user", "content": "Hello!"}],
|
|
63
|
+
"stream": false
|
|
64
|
+
}'
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 流式响应
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
curl http://localhost:8080/v1/chat/completions \
|
|
71
|
+
-H "Content-Type: application/json" \
|
|
72
|
+
-H "Authorization: Bearer sk-anything" \
|
|
73
|
+
-d '{
|
|
74
|
+
"model": "iflow-default",
|
|
75
|
+
"messages": [{"role": "user", "content": "讲个故事"}],
|
|
76
|
+
"stream": true
|
|
77
|
+
}'
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 模型列表
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
curl http://localhost:8080/v1/models
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 健康检查
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
curl http://localhost:8080/health
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## CLI 选项
|
|
93
|
+
|
|
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
|
+
```
|
|
106
|
+
|
|
107
|
+
## 配置文件
|
|
108
|
+
|
|
109
|
+
创建 `iflow-api.config.json`:
|
|
110
|
+
|
|
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
|
+
```
|
|
121
|
+
|
|
122
|
+
配置文件优先级(从高到低):
|
|
123
|
+
1. CLI 参数
|
|
124
|
+
2. 环境变量
|
|
125
|
+
3. 配置文件
|
|
126
|
+
4. 默认值
|
|
127
|
+
|
|
128
|
+
## 环境变量
|
|
129
|
+
|
|
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
|
+
└─────────────┘ └─────────────┘ └─────────┘
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 许可证
|
|
194
|
+
|
|
195
|
+
MIT
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iFlow SDK 适配器(使用子进程模式)
|
|
3
|
+
* 封装与 iFlow CLI 的通信
|
|
4
|
+
*/
|
|
5
|
+
export interface IFlowResponse {
|
|
6
|
+
content: string;
|
|
7
|
+
toolCalls?: Array<{
|
|
8
|
+
name: string;
|
|
9
|
+
status: string;
|
|
10
|
+
}>;
|
|
11
|
+
stopReason: 'end_turn' | 'max_tokens' | 'error';
|
|
12
|
+
}
|
|
13
|
+
export interface StreamChunk {
|
|
14
|
+
type: 'content' | 'tool_call' | 'done' | 'error';
|
|
15
|
+
content?: string;
|
|
16
|
+
toolName?: string;
|
|
17
|
+
toolStatus?: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface IFlowAdapterOptions {
|
|
21
|
+
model?: string;
|
|
22
|
+
apiKey?: string;
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
timeout?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* iFlow 适配器 - 使用子进程模式
|
|
28
|
+
*/
|
|
29
|
+
export declare class IFlowAdapter {
|
|
30
|
+
private options;
|
|
31
|
+
private defaultTimeout;
|
|
32
|
+
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
|
+
*/
|
|
44
|
+
private parseResponse;
|
|
45
|
+
/**
|
|
46
|
+
* 连接到 iFlow
|
|
47
|
+
*/
|
|
48
|
+
connect(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* 断开连接
|
|
51
|
+
*/
|
|
52
|
+
disconnect(): void;
|
|
53
|
+
/**
|
|
54
|
+
* 检查是否已连接
|
|
55
|
+
*/
|
|
56
|
+
isConnected(): boolean;
|
|
57
|
+
}
|
|
58
|
+
export default IFlowAdapter;
|
|
59
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/adapter.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* iFlow SDK 适配器(使用子进程模式)
|
|
4
|
+
* 封装与 iFlow CLI 的通信
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.IFlowAdapter = void 0;
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
/**
|
|
10
|
+
* iFlow 适配器 - 使用子进程模式
|
|
11
|
+
*/
|
|
12
|
+
class IFlowAdapter {
|
|
13
|
+
options;
|
|
14
|
+
defaultTimeout = 120000; // 2分钟默认超时
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 发送消息并获取完整响应(非流式)
|
|
20
|
+
*/
|
|
21
|
+
async sendMessage(prompt) {
|
|
22
|
+
console.log('[Adapter] 发送消息(非流式):', prompt.substring(0, 100));
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const args = ['-p', prompt];
|
|
25
|
+
if (this.options.model) {
|
|
26
|
+
args.push('-m', this.options.model);
|
|
27
|
+
}
|
|
28
|
+
console.log('[Adapter] 启动 iflow:', args.join(' '));
|
|
29
|
+
const child = (0, child_process_1.spawn)('iflow', args, {
|
|
30
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
31
|
+
});
|
|
32
|
+
let stdout = '';
|
|
33
|
+
let stderr = '';
|
|
34
|
+
const timeout = setTimeout(() => {
|
|
35
|
+
child.kill('SIGTERM');
|
|
36
|
+
reject(new Error(`iFlow 响应超时 (${this.defaultTimeout}ms)`));
|
|
37
|
+
}, this.options.timeout || this.defaultTimeout);
|
|
38
|
+
child.stdout?.on('data', (data) => {
|
|
39
|
+
stdout += data.toString();
|
|
40
|
+
});
|
|
41
|
+
child.stderr?.on('data', (data) => {
|
|
42
|
+
stderr += data.toString();
|
|
43
|
+
});
|
|
44
|
+
child.on('error', (err) => {
|
|
45
|
+
clearTimeout(timeout);
|
|
46
|
+
reject(new Error(`启动 iFlow 失败: ${err.message}`));
|
|
47
|
+
});
|
|
48
|
+
child.on('exit', (code) => {
|
|
49
|
+
clearTimeout(timeout);
|
|
50
|
+
console.log('[Adapter] iFlow 退出,code:', code);
|
|
51
|
+
if (code !== 0 && code !== null) {
|
|
52
|
+
console.error('[Adapter] iFlow stderr:', stderr);
|
|
53
|
+
}
|
|
54
|
+
// 解析响应
|
|
55
|
+
const content = this.parseResponse(stdout);
|
|
56
|
+
resolve({
|
|
57
|
+
content,
|
|
58
|
+
stopReason: code === 0 ? 'end_turn' : 'error',
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 发送消息并获取流式响应
|
|
65
|
+
*/
|
|
66
|
+
async *sendMessageStream(prompt) {
|
|
67
|
+
console.log('[Adapter] 发送消息(流式):', prompt.substring(0, 100));
|
|
68
|
+
const args = ['-p', prompt];
|
|
69
|
+
if (this.options.model) {
|
|
70
|
+
args.push('-m', this.options.model);
|
|
71
|
+
}
|
|
72
|
+
console.log('[Adapter] 启动 iflow:', args.join(' '));
|
|
73
|
+
const child = (0, child_process_1.spawn)('iflow', args, {
|
|
74
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
75
|
+
});
|
|
76
|
+
let buffer = '';
|
|
77
|
+
let isDone = false;
|
|
78
|
+
const timeout = setTimeout(() => {
|
|
79
|
+
if (!isDone) {
|
|
80
|
+
child.kill('SIGTERM');
|
|
81
|
+
isDone = true;
|
|
82
|
+
console.error('[Adapter] 流式响应超时');
|
|
83
|
+
}
|
|
84
|
+
}, this.options.timeout || this.defaultTimeout);
|
|
85
|
+
child.stdout?.on('data', (data) => {
|
|
86
|
+
buffer += data.toString();
|
|
87
|
+
});
|
|
88
|
+
child.stderr?.on('data', (data) => {
|
|
89
|
+
const msg = data.toString();
|
|
90
|
+
console.log('[Adapter] iFlow stderr:', msg.trim());
|
|
91
|
+
});
|
|
92
|
+
// 模拟流式输出 - 逐字符发送
|
|
93
|
+
let lastSentIndex = 0;
|
|
94
|
+
while (!isDone) {
|
|
95
|
+
// 检查进程是否结束
|
|
96
|
+
if (child.exitCode !== null) {
|
|
97
|
+
isDone = true;
|
|
98
|
+
}
|
|
99
|
+
// 发送新内容
|
|
100
|
+
if (buffer.length > lastSentIndex) {
|
|
101
|
+
const newContent = buffer.slice(lastSentIndex);
|
|
102
|
+
lastSentIndex = buffer.length;
|
|
103
|
+
// 逐行或逐字符发送
|
|
104
|
+
const lines = newContent.split('\n');
|
|
105
|
+
for (const line of lines) {
|
|
106
|
+
if (line.trim()) {
|
|
107
|
+
yield {
|
|
108
|
+
type: 'content',
|
|
109
|
+
content: line + '\n',
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (!isDone) {
|
|
115
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
clearTimeout(timeout);
|
|
119
|
+
// 发送剩余内容
|
|
120
|
+
if (buffer.length > lastSentIndex) {
|
|
121
|
+
yield {
|
|
122
|
+
type: 'content',
|
|
123
|
+
content: buffer.slice(lastSentIndex),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
yield { type: 'done' };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 解析 iFlow 输出,提取实际回复内容
|
|
130
|
+
*/
|
|
131
|
+
parseResponse(stdout) {
|
|
132
|
+
// 尝试提取 <Execution Info> 之前的内容作为回复
|
|
133
|
+
const executionInfoMatch = stdout.match(/<Execution Info>[\s\S]*$/);
|
|
134
|
+
if (executionInfoMatch) {
|
|
135
|
+
return stdout.substring(0, executionInfoMatch.index).trim();
|
|
136
|
+
}
|
|
137
|
+
// 如果没有 Execution Info,返回全部内容(去掉开头的警告)
|
|
138
|
+
const lines = stdout.split('\n');
|
|
139
|
+
const startIndex = lines.findIndex((line) => !line.includes('DeprecationWarning') &&
|
|
140
|
+
!line.includes('node:') &&
|
|
141
|
+
line.trim());
|
|
142
|
+
if (startIndex >= 0) {
|
|
143
|
+
return lines.slice(startIndex).join('\n').trim();
|
|
144
|
+
}
|
|
145
|
+
return stdout.trim();
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 连接到 iFlow
|
|
149
|
+
*/
|
|
150
|
+
async connect() {
|
|
151
|
+
// 子进程模式不需要持久连接
|
|
152
|
+
console.log('[Adapter] 子进程模式已就绪');
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 断开连接
|
|
156
|
+
*/
|
|
157
|
+
disconnect() {
|
|
158
|
+
// 子进程模式不需要断开连接
|
|
159
|
+
console.log('[Adapter] 子进程模式断开(无操作)');
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* 检查是否已连接
|
|
163
|
+
*/
|
|
164
|
+
isConnected() {
|
|
165
|
+
// 子进程模式总是"已连接"
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.IFlowAdapter = IFlowAdapter;
|
|
170
|
+
exports.default = IFlowAdapter;
|
|
171
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;GAEG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* CLI 入口
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const server_js_1 = require("./server.js");
|
|
9
|
+
const config_js_1 = require("./config.js");
|
|
10
|
+
const program = new commander_1.Command();
|
|
11
|
+
program
|
|
12
|
+
.name('iflow-api-server')
|
|
13
|
+
.description('将 iFlow LLM 服务暴露为 OpenAI 兼容 API')
|
|
14
|
+
.version('0.1.0');
|
|
15
|
+
program
|
|
16
|
+
.option('-p, --port <port>', '服务端口', '8080')
|
|
17
|
+
.option('-h, --host <host>', '服务主机', '0.0.0.0')
|
|
18
|
+
.option('--no-cors', '禁用 CORS')
|
|
19
|
+
.option('-k, --api-key <key>', 'API Key 认证')
|
|
20
|
+
.option('-m, --model <model>', '指定使用的模型 (如 claude, gpt-4)', 'kimi-k2.5')
|
|
21
|
+
.option('-c, --config <path>', '配置文件路径')
|
|
22
|
+
.option('--log-level <level>', '日志级别 (DEBUG|INFO|WARN|ERROR)', 'INFO')
|
|
23
|
+
.action(async (options) => {
|
|
24
|
+
try {
|
|
25
|
+
// 加载配置
|
|
26
|
+
const fileConfig = (0, config_js_1.loadConfig)(options.config);
|
|
27
|
+
const envConfig = (0, config_js_1.loadEnvConfig)();
|
|
28
|
+
const cliConfig = {
|
|
29
|
+
port: options.port ? parseInt(options.port, 10) : undefined,
|
|
30
|
+
host: options.host,
|
|
31
|
+
cors: options.cors,
|
|
32
|
+
apiKey: options.apiKey,
|
|
33
|
+
model: options.model,
|
|
34
|
+
logLevel: options.logLevel,
|
|
35
|
+
};
|
|
36
|
+
// 合并配置
|
|
37
|
+
const config = (0, config_js_1.mergeConfig)(fileConfig, envConfig, cliConfig);
|
|
38
|
+
// 创建并启动服务器
|
|
39
|
+
const server = new server_js_1.IFlowAPIServer(config);
|
|
40
|
+
// 处理退出信号
|
|
41
|
+
const shutdown = async (signal) => {
|
|
42
|
+
console.log(`\n${signal} 收到,正在关闭服务器...`);
|
|
43
|
+
await server.stop();
|
|
44
|
+
process.exit(0);
|
|
45
|
+
};
|
|
46
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
47
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
48
|
+
// 启动
|
|
49
|
+
await server.start();
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.error('启动失败:', error);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
program.parse();
|
|
57
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AAEA;;GAEG;;AAEH,yCAAoC;AACpC,2CAA6C;AAC7C,2CAAkF;AAElF,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,kBAAkB,CAAC;KACxB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,MAAM,CAAC,mBAAmB,EAAE,MAAM,EAAE,MAAM,CAAC;KAC3C,MAAM,CAAC,mBAAmB,EAAE,MAAM,EAAE,SAAS,CAAC;KAC9C,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC;KAC9B,MAAM,CAAC,qBAAqB,EAAE,YAAY,CAAC;KAC3C,MAAM,CAAC,qBAAqB,EAAE,2BAA2B,EAAE,WAAW,CAAC;KACvE,MAAM,CAAC,qBAAqB,EAAE,QAAQ,CAAC;KACvC,MAAM,CAAC,qBAAqB,EAAE,8BAA8B,EAAE,MAAM,CAAC;KACrE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,OAAO;QACP,MAAM,UAAU,GAAG,IAAA,sBAAU,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,IAAA,yBAAa,GAAE,CAAC;QAClC,MAAM,SAAS,GAAoB;YACjC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;YAC3D,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC;QAEF,OAAO;QACP,MAAM,MAAM,GAAG,IAAA,uBAAW,EAAC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAE7D,WAAW;QACX,MAAM,MAAM,GAAG,IAAI,0BAAc,CAAC,MAAM,CAAC,CAAC;QAE1C,SAAS;QACT,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;YACxC,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,gBAAgB,CAAC,CAAC;YACzC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;QAEjD,KAAK;QACL,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 配置管理
|
|
3
|
+
*/
|
|
4
|
+
export interface Config {
|
|
5
|
+
port: number;
|
|
6
|
+
host: string;
|
|
7
|
+
cors: boolean;
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
model?: string;
|
|
10
|
+
logLevel: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';
|
|
11
|
+
}
|
|
12
|
+
export declare const DEFAULT_CONFIG: Config;
|
|
13
|
+
/**
|
|
14
|
+
* 从文件加载配置
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadConfig(configPath?: string): Partial<Config>;
|
|
17
|
+
/**
|
|
18
|
+
* 从环境变量加载配置
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadEnvConfig(): Partial<Config>;
|
|
21
|
+
/**
|
|
22
|
+
* 合并配置
|
|
23
|
+
*/
|
|
24
|
+
export declare function mergeConfig(fileConfig: Partial<Config>, envConfig: Partial<Config>, cliConfig: Partial<Config>): Config;
|
|
25
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAC/C;AAED,eAAO,MAAM,cAAc,EAAE,MAM5B,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB/D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CA+B/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,EAC3B,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,EAC1B,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,GACzB,MAAM,CAOR"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 配置管理
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_CONFIG = void 0;
|
|
7
|
+
exports.loadConfig = loadConfig;
|
|
8
|
+
exports.loadEnvConfig = loadEnvConfig;
|
|
9
|
+
exports.mergeConfig = mergeConfig;
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const path_1 = require("path");
|
|
12
|
+
exports.DEFAULT_CONFIG = {
|
|
13
|
+
port: 8080,
|
|
14
|
+
host: '0.0.0.0',
|
|
15
|
+
cors: true,
|
|
16
|
+
model: 'kimi-k2.5',
|
|
17
|
+
logLevel: 'INFO',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* 从文件加载配置
|
|
21
|
+
*/
|
|
22
|
+
function loadConfig(configPath) {
|
|
23
|
+
const paths = configPath
|
|
24
|
+
? [configPath]
|
|
25
|
+
: [
|
|
26
|
+
'./iflow-api.config.json',
|
|
27
|
+
'./.iflow-api.json',
|
|
28
|
+
'~/.iflow-api/config.json',
|
|
29
|
+
];
|
|
30
|
+
for (const path of paths) {
|
|
31
|
+
const fullPath = (0, path_1.resolve)(path.replace(/^~/, process.env.HOME || ''));
|
|
32
|
+
if ((0, fs_1.existsSync)(fullPath)) {
|
|
33
|
+
try {
|
|
34
|
+
const content = (0, fs_1.readFileSync)(fullPath, 'utf-8');
|
|
35
|
+
return JSON.parse(content);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.warn(`无法加载配置文件 ${path}:`, error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 从环境变量加载配置
|
|
46
|
+
*/
|
|
47
|
+
function loadEnvConfig() {
|
|
48
|
+
const config = {};
|
|
49
|
+
if (process.env.IFLOW_API_PORT) {
|
|
50
|
+
config.port = parseInt(process.env.IFLOW_API_PORT, 10);
|
|
51
|
+
}
|
|
52
|
+
if (process.env.IFLOW_API_HOST) {
|
|
53
|
+
config.host = process.env.IFLOW_API_HOST;
|
|
54
|
+
}
|
|
55
|
+
if (process.env.IFLOW_API_KEY) {
|
|
56
|
+
config.apiKey = process.env.IFLOW_API_KEY;
|
|
57
|
+
}
|
|
58
|
+
if (process.env.IFLOW_API_LOG_LEVEL) {
|
|
59
|
+
const level = process.env.IFLOW_API_LOG_LEVEL;
|
|
60
|
+
if (['DEBUG', 'INFO', 'WARN', 'ERROR'].includes(level)) {
|
|
61
|
+
config.logLevel = level;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (process.env.IFLOW_API_CORS) {
|
|
65
|
+
config.cors = process.env.IFLOW_API_CORS === 'true';
|
|
66
|
+
}
|
|
67
|
+
if (process.env.IFLOW_API_MODEL) {
|
|
68
|
+
config.model = process.env.IFLOW_API_MODEL;
|
|
69
|
+
}
|
|
70
|
+
return config;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 合并配置
|
|
74
|
+
*/
|
|
75
|
+
function mergeConfig(fileConfig, envConfig, cliConfig) {
|
|
76
|
+
return {
|
|
77
|
+
...exports.DEFAULT_CONFIG,
|
|
78
|
+
...fileConfig,
|
|
79
|
+
...envConfig,
|
|
80
|
+
...cliConfig,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAyBH,gCAsBC;AAKD,sCA+BC;AAKD,kCAWC;AAjGD,2BAA8C;AAC9C,+BAA+B;AAWlB,QAAA,cAAc,GAAW;IACpC,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,MAAM;CACjB,CAAC;AAEF;;GAEG;AACH,SAAgB,UAAU,CAAC,UAAmB;IAC5C,MAAM,KAAK,GAAG,UAAU;QACtB,CAAC,CAAC,CAAC,UAAU,CAAC;QACd,CAAC,CAAC;YACE,yBAAyB;YACzB,mBAAmB;YACnB,0BAA0B;SAC3B,CAAC;IAEN,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAA,cAAO,EAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QACrE,IAAI,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAChD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa;IAC3B,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC5C,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAyC,CAAC;QACpE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACvD,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,CAAC;IACtD,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC7C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CACzB,UAA2B,EAC3B,SAA0B,EAC1B,SAA0B;IAE1B,OAAO;QACL,GAAG,sBAAc;QACjB,GAAG,UAAU;QACb,GAAG,SAAS;QACZ,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iFlow API Bridge
|
|
3
|
+
* 将 iFlow LLM 服务暴露为 OpenAI 兼容 API
|
|
4
|
+
*/
|
|
5
|
+
export { IFlowAdapter, type IFlowResponse, type StreamChunk } from './adapter.js';
|
|
6
|
+
export { IFlowAPIServer, type ServerOptions } from './server.js';
|
|
7
|
+
export { loadConfig, loadEnvConfig, mergeConfig, DEFAULT_CONFIG, type Config, } from './config.js';
|
|
8
|
+
export * from './openai/types.js';
|
|
9
|
+
export { generateId, getTimestamp, messagesToIFlowPrompt, createCompletionResponse, createStreamChunk, calculateUsage, formatSSE, SSE_DONE, AVAILABLE_MODELS, getDefaultModel, } from './openai/transformer.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACL,UAAU,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,KAAK,MAAM,GACZ,MAAM,aAAa,CAAC;AACrB,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,eAAe,GAChB,MAAM,yBAAyB,CAAC"}
|