@asframe/opencode-iflow-auth 1.0.0 → 1.0.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 +151 -27
- package/dist/iflow/proxy.d.ts +2 -0
- package/dist/iflow/proxy.js +97 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,56 @@ OpenCode plugin for iFlow.cn providing access to Qwen, DeepSeek, Kimi, GLM, and
|
|
|
16
16
|
- **Native thinking mode**: Support for GLM-4.x, GLM-5 and DeepSeek R1 models.
|
|
17
17
|
- **Configurable timeout**: Request timeout and iteration limits to prevent hangs.
|
|
18
18
|
- **Automatic port selection**: OAuth callback server port conflict avoidance.
|
|
19
|
+
- **Auto-install CLI**: Automatically install iflow CLI if not found.
|
|
20
|
+
|
|
21
|
+
## Supported Models
|
|
22
|
+
|
|
23
|
+
### API Key Mode (`iflow` provider)
|
|
24
|
+
|
|
25
|
+
Models available via OAuth 2.0 or API Key authentication:
|
|
26
|
+
|
|
27
|
+
| Model | Context | Output | Description |
|
|
28
|
+
|-------|---------|--------|-------------|
|
|
29
|
+
| `deepseek-v3` | 128K | 32K | DeepSeek V3 |
|
|
30
|
+
| `deepseek-v3.2` | 128K | 64K | DeepSeek V3.2 |
|
|
31
|
+
| `deepseek-r1` | 128K | 32K | DeepSeek R1 (Thinking) |
|
|
32
|
+
| `glm-4.6` | 200K | 128K | GLM-4.6 (Reasoning, Vision) |
|
|
33
|
+
| `glm-4.7` | 256K | 64K | GLM-4.7 (Latest, Reasoning, Vision) |
|
|
34
|
+
| `qwen3-max` | 256K | 32K | Qwen3 Max |
|
|
35
|
+
| `qwen3-max-preview` | 256K | 32K | Qwen3 Max Preview |
|
|
36
|
+
| `qwen3-coder-plus` | 1M | 64K | Qwen3 Coder Plus |
|
|
37
|
+
| `qwen3-vl-plus` | 256K | 32K | Qwen3 VL Plus (Vision) |
|
|
38
|
+
| `qwen3-32b` | 128K | 32K | Qwen3 32B |
|
|
39
|
+
| `qwen3-235b` | 256K | 64K | Qwen3 235B |
|
|
40
|
+
| `qwen3-235b-a22b-thinking-2507` | 256K | 64K | Qwen3 235B Thinking |
|
|
41
|
+
| `qwen3-235b-a22b-instruct` | 256K | 64K | Qwen3 235B Instruct |
|
|
42
|
+
| `kimi-k2` | 128K | 64K | Kimi K2 |
|
|
43
|
+
| `kimi-k2-0905` | 256K | 64K | Kimi K2 0905 |
|
|
44
|
+
| `iflow-rome-30ba3b` | 256K | 64K | iFlow ROME 30B |
|
|
45
|
+
|
|
46
|
+
### CLI Proxy Mode (`iflow-proxy` provider)
|
|
47
|
+
|
|
48
|
+
**All models from API Key Mode** PLUS these exclusive models:
|
|
49
|
+
|
|
50
|
+
| Model | Context | Output | Description |
|
|
51
|
+
|-------|---------|--------|-------------|
|
|
52
|
+
| `glm-5` | 256K | 64K | GLM-5 - Flagship model (744B params, 40B active), best for reasoning & coding |
|
|
53
|
+
| `glm-5-free` | 256K | 64K | GLM-5 Free - Same capabilities as glm-5, free for limited time |
|
|
54
|
+
| `glm-5-thinking` | 256K | 64K | GLM-5 Thinking - Enhanced "System 2" deep reasoning capabilities |
|
|
55
|
+
|
|
56
|
+
**GLM-5 Model Family:**
|
|
57
|
+
|
|
58
|
+
| Model | Description |
|
|
59
|
+
|-------|-------------|
|
|
60
|
+
| `glm-5` | Latest flagship model from Zhipu AI. 744B parameters (40B active), 28.5T tokens. Best-in-class for reasoning, coding, and agentic tasks. |
|
|
61
|
+
| `glm-5-free` | Free access to GLM-5 during promotional period. Same capabilities, no cost. |
|
|
62
|
+
| `glm-5-thinking` | Enhanced deep reasoning mode. Excels at complex architectural problems and "System 2" thinking. |
|
|
63
|
+
|
|
64
|
+
**Summary:**
|
|
65
|
+
- **API Key Mode**: 16 models
|
|
66
|
+
- **CLI Proxy Mode**: 19 models (16 + 3 exclusive)
|
|
67
|
+
|
|
68
|
+
**Note**: CLI Proxy mode can also be used if you prefer CLI authentication over API Key for any model.
|
|
19
69
|
|
|
20
70
|
## Two Plugin Modes
|
|
21
71
|
|
|
@@ -29,7 +79,7 @@ Direct API calls to iFlow.cn for standard models.
|
|
|
29
79
|
|----------|-------|
|
|
30
80
|
| Provider | `iflow` |
|
|
31
81
|
| baseURL | `https://apis.iflow.cn/v1` |
|
|
32
|
-
|
|
|
82
|
+
| Auth | OAuth 2.0 / API Key |
|
|
33
83
|
|
|
34
84
|
### 2. `IFlowProxyPlugin` - CLI Proxy Mode
|
|
35
85
|
|
|
@@ -39,7 +89,7 @@ Routes requests through iflow CLI for GLM-5 support. The proxy server starts aut
|
|
|
39
89
|
|----------|-------|
|
|
40
90
|
| Provider | `iflow-proxy` |
|
|
41
91
|
| Proxy Port | `127.0.0.1:19998` |
|
|
42
|
-
|
|
|
92
|
+
| Auth | iflow CLI login |
|
|
43
93
|
|
|
44
94
|
**How it works:**
|
|
45
95
|
1. Plugin detects if model requires CLI (glm-5, glm-5-free, glm-5-thinking)
|
|
@@ -49,8 +99,18 @@ Routes requests through iflow CLI for GLM-5 support. The proxy server starts aut
|
|
|
49
99
|
|
|
50
100
|
## Installation
|
|
51
101
|
|
|
102
|
+
### Quick Start
|
|
103
|
+
|
|
52
104
|
Add the plugin to your `opencode.json` or `opencode.jsonc`:
|
|
53
105
|
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"plugin": ["@asframe/opencode-iflow-auth"]
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Full Configuration
|
|
113
|
+
|
|
54
114
|
```json
|
|
55
115
|
{
|
|
56
116
|
"plugin": ["@asframe/opencode-iflow-auth"],
|
|
@@ -71,9 +131,9 @@ Add the plugin to your `opencode.json` or `opencode.jsonc`:
|
|
|
71
131
|
"limit": { "context": 128000, "output": 64000 },
|
|
72
132
|
"modalities": { "input": ["text"], "output": ["text"] }
|
|
73
133
|
},
|
|
74
|
-
"kimi-k2
|
|
75
|
-
"name": "Kimi K2
|
|
76
|
-
"limit": { "context":
|
|
134
|
+
"kimi-k2": {
|
|
135
|
+
"name": "Kimi K2",
|
|
136
|
+
"limit": { "context": 128000, "output": 64000 },
|
|
77
137
|
"modalities": { "input": ["text"], "output": ["text"] }
|
|
78
138
|
},
|
|
79
139
|
"qwen3-coder-plus": {
|
|
@@ -91,17 +151,17 @@ Add the plugin to your `opencode.json` or `opencode.jsonc`:
|
|
|
91
151
|
"models": {
|
|
92
152
|
"glm-5": {
|
|
93
153
|
"name": "GLM-5 (via CLI Proxy)",
|
|
94
|
-
"limit": { "context":
|
|
95
|
-
"modalities": { "input": ["text"], "output": ["text"] }
|
|
154
|
+
"limit": { "context": 256000, "output": 64000 },
|
|
155
|
+
"modalities": { "input": ["text", "image"], "output": ["text"] }
|
|
96
156
|
},
|
|
97
157
|
"glm-5-free": {
|
|
98
158
|
"name": "GLM-5 Free (via CLI Proxy)",
|
|
99
|
-
"limit": { "context":
|
|
159
|
+
"limit": { "context": 256000, "output": 64000 },
|
|
100
160
|
"modalities": { "input": ["text"], "output": ["text"] }
|
|
101
161
|
},
|
|
102
162
|
"glm-5-thinking": {
|
|
103
163
|
"name": "GLM-5 Thinking (via CLI Proxy)",
|
|
104
|
-
"limit": { "context":
|
|
164
|
+
"limit": { "context": 256000, "output": 64000 },
|
|
105
165
|
"modalities": { "input": ["text"], "output": ["text"] }
|
|
106
166
|
}
|
|
107
167
|
}
|
|
@@ -149,7 +209,7 @@ export IFLOW_AUTO_INSTALL_CLI=true
|
|
|
149
209
|
# Direct API mode
|
|
150
210
|
opencode run "你好" --model iflow/deepseek-v3.2
|
|
151
211
|
opencode run "你好" --model iflow/glm-4.6
|
|
152
|
-
opencode run "你好" --model iflow/kimi-k2
|
|
212
|
+
opencode run "你好" --model iflow/kimi-k2
|
|
153
213
|
|
|
154
214
|
# CLI Proxy mode (GLM-5)
|
|
155
215
|
opencode run "你好" --model iflow-proxy/glm-5
|
|
@@ -174,26 +234,31 @@ Edit `~/.config/opencode/iflow.json`:
|
|
|
174
234
|
|
|
175
235
|
### Configuration Options
|
|
176
236
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
237
|
+
| Option | Type | Default | Description |
|
|
238
|
+
|--------|------|---------|-------------|
|
|
239
|
+
| `default_auth_method` | string | `oauth` | Default authentication method (`oauth`, `apikey`) |
|
|
240
|
+
| `account_selection_strategy` | string | `sticky` | Account rotation strategy (`sticky`, `round-robin`) |
|
|
241
|
+
| `auth_server_port_start` | number | `8087` | Starting port for OAuth callback server (1024-65535) |
|
|
242
|
+
| `auth_server_port_range` | number | `10` | Number of ports to try (1-100) |
|
|
243
|
+
| `max_request_iterations` | number | `50` | Maximum loop iterations to prevent hangs (10-1000) |
|
|
244
|
+
| `request_timeout_ms` | number | `300000` | Request timeout in milliseconds (60000-600000ms) |
|
|
245
|
+
| `enable_log_api_request` | boolean | `false` | Enable API request/response logging |
|
|
184
246
|
|
|
185
247
|
### Environment Variables
|
|
186
248
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
- `
|
|
192
|
-
- `
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
249
|
+
| Variable | Description |
|
|
250
|
+
|----------|-------------|
|
|
251
|
+
| `IFLOW_AUTH_DEBUG` | Enable debug logging for auth plugin (`true`/`false`) |
|
|
252
|
+
| `IFLOW_PROXY_DEBUG` | Enable debug logging for proxy plugin (`true`/`false`) |
|
|
253
|
+
| `IFLOW_AUTO_INSTALL_CLI` | Auto-install iflow CLI if not installed (`true`/`false`) |
|
|
254
|
+
| `IFLOW_AUTO_LOGIN` | Auto-trigger iflow login if not logged in (`true`/`false`) |
|
|
255
|
+
| `IFLOW_DEFAULT_AUTH_METHOD` | Override default auth method |
|
|
256
|
+
| `IFLOW_ACCOUNT_SELECTION_STRATEGY` | Override account selection strategy |
|
|
257
|
+
| `IFLOW_AUTH_SERVER_PORT_START` | Override OAuth server port |
|
|
258
|
+
| `IFLOW_AUTH_SERVER_PORT_RANGE` | Override OAuth server port range |
|
|
259
|
+
| `IFLOW_MAX_REQUEST_ITERATIONS` | Override max iterations |
|
|
260
|
+
| `IFLOW_REQUEST_TIMEOUT_MS` | Override request timeout |
|
|
261
|
+
| `IFLOW_ENABLE_LOG_API_REQUEST` | Enable API logging |
|
|
197
262
|
|
|
198
263
|
## Storage
|
|
199
264
|
|
|
@@ -261,6 +326,64 @@ Get-Process -Id (Get-NetTCPConnection -LocalPort 19998).OwningProcess | Stop-Pro
|
|
|
261
326
|
lsof -i :19998 | grep LISTEN | awk '{print $2}' | xargs kill -9
|
|
262
327
|
```
|
|
263
328
|
|
|
329
|
+
### Authentication Issues
|
|
330
|
+
|
|
331
|
+
1. **API Key not working:**
|
|
332
|
+
- Ensure your API key starts with `sk-`
|
|
333
|
+
- Check if the key is valid at [iFlow.cn](https://iflow.cn)
|
|
334
|
+
|
|
335
|
+
2. **OAuth not working:**
|
|
336
|
+
- Clear browser cookies
|
|
337
|
+
- Try a different browser
|
|
338
|
+
- Check if the callback port is available
|
|
339
|
+
|
|
340
|
+
## FAQ
|
|
341
|
+
|
|
342
|
+
### Q: Why do I need CLI Proxy for GLM-5?
|
|
343
|
+
|
|
344
|
+
GLM-5 requires special authentication that is only available through the iflow CLI. The CLI Proxy mode bridges this gap by routing requests through the CLI.
|
|
345
|
+
|
|
346
|
+
### Q: Can I use both modes at the same time?
|
|
347
|
+
|
|
348
|
+
Yes! You can configure both `iflow` and `iflow-proxy` providers and use them interchangeably.
|
|
349
|
+
|
|
350
|
+
### Q: Is this plugin official?
|
|
351
|
+
|
|
352
|
+
No, this is an independent implementation and is not affiliated with, endorsed by, or supported by iFlow.cn.
|
|
353
|
+
|
|
354
|
+
### Q: How do I get an API key?
|
|
355
|
+
|
|
356
|
+
1. Visit [iFlow.cn](https://iflow.cn)
|
|
357
|
+
2. Create an account or login
|
|
358
|
+
3. Go to API settings
|
|
359
|
+
4. Generate a new API key
|
|
360
|
+
|
|
361
|
+
## Changelog
|
|
362
|
+
|
|
363
|
+
### v1.0.1
|
|
364
|
+
- Added GLM-4.7 model support
|
|
365
|
+
- Improved README documentation with clearer model comparison
|
|
366
|
+
- Added detailed GLM-5 model family description
|
|
367
|
+
- Updated model counts (16 API Key models, 19 CLI Proxy models)
|
|
368
|
+
|
|
369
|
+
### v1.0.0
|
|
370
|
+
- Initial release
|
|
371
|
+
- Dual authentication (OAuth 2.0 / API Key)
|
|
372
|
+
- CLI Proxy mode for GLM-5
|
|
373
|
+
- Auto-install CLI feature
|
|
374
|
+
- Multi-account rotation
|
|
375
|
+
- Thinking model support
|
|
376
|
+
|
|
377
|
+
## Contributing
|
|
378
|
+
|
|
379
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
380
|
+
|
|
381
|
+
1. Fork the repository
|
|
382
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
383
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
384
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
385
|
+
5. Open a Pull Request
|
|
386
|
+
|
|
264
387
|
## License
|
|
265
388
|
|
|
266
389
|
MIT License - see [LICENSE](LICENSE) for details.
|
|
@@ -276,3 +399,4 @@ Feel free to open a PR to optimize this plugin further.
|
|
|
276
399
|
- [GitHub Repository](https://github.com/asframe/opencode-iflow-auth)
|
|
277
400
|
- [npm Package](https://www.npmjs.com/package/@asframe/opencode-iflow-auth)
|
|
278
401
|
- [iFlow.cn](https://iflow.cn)
|
|
402
|
+
- [OpenCode](https://opencode.ai)
|
package/dist/iflow/proxy.d.ts
CHANGED
|
@@ -3,12 +3,14 @@ export declare class IFlowCLIProxy {
|
|
|
3
3
|
private port;
|
|
4
4
|
private host;
|
|
5
5
|
private cliAvailable;
|
|
6
|
+
private cliLoggedIn;
|
|
6
7
|
private cliChecked;
|
|
7
8
|
constructor(port?: number, host?: string);
|
|
8
9
|
start(): Promise<void>;
|
|
9
10
|
stop(): Promise<void>;
|
|
10
11
|
getBaseUrl(): string;
|
|
11
12
|
isCLIAvailable(): boolean;
|
|
13
|
+
isCLILoggedIn(): boolean;
|
|
12
14
|
private handleRequest;
|
|
13
15
|
private handleChatCompletions;
|
|
14
16
|
private handleDirectAPIRequest;
|
package/dist/iflow/proxy.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { spawn, execSync } from 'child_process';
|
|
1
|
+
import { spawn, execSync, exec } from 'child_process';
|
|
2
2
|
import { createServer } from 'http';
|
|
3
3
|
import { randomUUID } from 'crypto';
|
|
4
4
|
const IFLOW_PROXY_PORT = 19998;
|
|
@@ -28,6 +28,50 @@ function checkIFlowCLI() {
|
|
|
28
28
|
return { installed: false, error: errorMsg };
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
function checkIFlowLogin() {
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
try {
|
|
34
|
+
exec('iflow whoami', { timeout: 5000 }, (error, stdout, stderr) => {
|
|
35
|
+
if (error) {
|
|
36
|
+
resolve({ loggedIn: false, error: error.message });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const output = stdout + stderr;
|
|
40
|
+
if (output.includes('Invalid token') || output.includes('not logged in') || output.includes('Please login')) {
|
|
41
|
+
resolve({ loggedIn: false, error: 'Not logged in' });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
resolve({ loggedIn: true });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
resolve({ loggedIn: false, error: error.message });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async function triggerIFlowLogin() {
|
|
53
|
+
log('Triggering iflow login...');
|
|
54
|
+
console.error('[IFlowProxy] Please login to iflow CLI...');
|
|
55
|
+
console.error('[IFlowProxy] Run: iflow login');
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
const loginProcess = spawn('iflow', ['login'], {
|
|
58
|
+
shell: true,
|
|
59
|
+
stdio: 'inherit'
|
|
60
|
+
});
|
|
61
|
+
loginProcess.on('close', (code) => {
|
|
62
|
+
if (code === 0) {
|
|
63
|
+
log('iflow login successful');
|
|
64
|
+
resolve({ success: true });
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
resolve({ success: false, error: `Login process exited with code ${code}` });
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
loginProcess.on('error', (err) => {
|
|
71
|
+
resolve({ success: false, error: err.message });
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
31
75
|
async function installIFlowCLI() {
|
|
32
76
|
log('Attempting to install iflow CLI...');
|
|
33
77
|
console.error('[IFlowProxy] Installing iflow CLI...');
|
|
@@ -64,6 +108,7 @@ export class IFlowCLIProxy {
|
|
|
64
108
|
port;
|
|
65
109
|
host;
|
|
66
110
|
cliAvailable = false;
|
|
111
|
+
cliLoggedIn = false;
|
|
67
112
|
cliChecked = false;
|
|
68
113
|
constructor(port = IFLOW_PROXY_PORT, host = IFLOW_PROXY_HOST) {
|
|
69
114
|
this.port = port;
|
|
@@ -83,18 +128,45 @@ export class IFlowCLIProxy {
|
|
|
83
128
|
}
|
|
84
129
|
this.cliAvailable = cliCheck.installed;
|
|
85
130
|
this.cliChecked = true;
|
|
131
|
+
if (cliCheck.installed) {
|
|
132
|
+
const loginCheck = await checkIFlowLogin();
|
|
133
|
+
this.cliLoggedIn = loginCheck.loggedIn;
|
|
134
|
+
if (!loginCheck.loggedIn) {
|
|
135
|
+
console.error('');
|
|
136
|
+
console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
|
|
137
|
+
console.error('[IFlowProxy] WARNING: iflow CLI is not logged in');
|
|
138
|
+
console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
|
|
139
|
+
console.error('[IFlowProxy] To use GLM-5 models, please login to iflow CLI:');
|
|
140
|
+
console.error('[IFlowProxy]');
|
|
141
|
+
console.error('[IFlowProxy] iflow login');
|
|
142
|
+
console.error('[IFlowProxy]');
|
|
143
|
+
console.error('[IFlowProxy] Or set IFLOW_AUTO_LOGIN=true to auto-trigger login');
|
|
144
|
+
console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
|
|
145
|
+
console.error('');
|
|
146
|
+
if (process.env.IFLOW_AUTO_LOGIN === 'true') {
|
|
147
|
+
const loginResult = await triggerIFlowLogin();
|
|
148
|
+
if (loginResult.success) {
|
|
149
|
+
this.cliLoggedIn = true;
|
|
150
|
+
console.error('[IFlowProxy] Login successful!');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
log('iflow CLI is logged in');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
86
158
|
if (!cliCheck.installed) {
|
|
87
159
|
console.error('');
|
|
88
|
-
console.error('[IFlowProxy]
|
|
160
|
+
console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
|
|
89
161
|
console.error('[IFlowProxy] WARNING: iflow CLI is not installed');
|
|
90
|
-
console.error('[IFlowProxy]
|
|
162
|
+
console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
|
|
91
163
|
console.error('[IFlowProxy] To use GLM-5 models, please install iflow CLI:');
|
|
92
164
|
console.error('[IFlowProxy]');
|
|
93
165
|
console.error('[IFlowProxy] npm install -g iflow-cli');
|
|
94
166
|
console.error('[IFlowProxy] iflow login');
|
|
95
167
|
console.error('[IFlowProxy]');
|
|
96
168
|
console.error('[IFlowProxy] Or set IFLOW_AUTO_INSTALL_CLI=true to auto-install');
|
|
97
|
-
console.error('[IFlowProxy]
|
|
169
|
+
console.error('[IFlowProxy] ══════════════════════════════════════════════════════════');
|
|
98
170
|
console.error('');
|
|
99
171
|
}
|
|
100
172
|
else {
|
|
@@ -138,6 +210,9 @@ export class IFlowCLIProxy {
|
|
|
138
210
|
isCLIAvailable() {
|
|
139
211
|
return this.cliAvailable;
|
|
140
212
|
}
|
|
213
|
+
isCLILoggedIn() {
|
|
214
|
+
return this.cliLoggedIn;
|
|
215
|
+
}
|
|
141
216
|
async handleRequest(req, res) {
|
|
142
217
|
if (req.method !== 'POST') {
|
|
143
218
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
@@ -169,11 +244,20 @@ export class IFlowCLIProxy {
|
|
|
169
244
|
log(`Request for model: ${model}, requires CLI: ${requiresCLI(model)}`);
|
|
170
245
|
if (requiresCLI(model)) {
|
|
171
246
|
if (!this.cliAvailable) {
|
|
172
|
-
log(`CLI not
|
|
247
|
+
log(`CLI not installed for model: ${model}`);
|
|
248
|
+
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
249
|
+
res.end(JSON.stringify({
|
|
250
|
+
error: 'iflow CLI is not installed. Please install it with: npm install -g iflow-cli',
|
|
251
|
+
install_hint: 'npm install -g iflow-cli'
|
|
252
|
+
}));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (!this.cliLoggedIn) {
|
|
256
|
+
log(`CLI not logged in for model: ${model}`);
|
|
173
257
|
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
174
258
|
res.end(JSON.stringify({
|
|
175
|
-
error: 'iflow CLI is not
|
|
176
|
-
|
|
259
|
+
error: 'iflow CLI is not logged in. Please run: iflow login',
|
|
260
|
+
login_hint: 'iflow login'
|
|
177
261
|
}));
|
|
178
262
|
return;
|
|
179
263
|
}
|
|
@@ -249,8 +333,8 @@ export class IFlowCLIProxy {
|
|
|
249
333
|
}],
|
|
250
334
|
usage: {
|
|
251
335
|
prompt_tokens: result.promptTokens || 0,
|
|
252
|
-
completion_tokens: result.completionTokens ||
|
|
253
|
-
total_tokens: (result.promptTokens ||
|
|
336
|
+
completion_tokens: result.completionTokens || 1,
|
|
337
|
+
total_tokens: (result.promptTokens || 1) + (result.completionTokens || 1)
|
|
254
338
|
}
|
|
255
339
|
};
|
|
256
340
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
@@ -345,7 +429,7 @@ export class IFlowCLIProxy {
|
|
|
345
429
|
reject(new Error(`Failed to start iflow: ${err.message}`));
|
|
346
430
|
});
|
|
347
431
|
iflow.on('close', (code) => {
|
|
348
|
-
if (code !==
|
|
432
|
+
if (code !== 1) {
|
|
349
433
|
log('iflow exited with code:', code, stderr);
|
|
350
434
|
reject(new Error(`iflow exited with code ${code}`));
|
|
351
435
|
return;
|
|
@@ -354,8 +438,8 @@ export class IFlowCLIProxy {
|
|
|
354
438
|
log('iflow response length:', content.length);
|
|
355
439
|
resolve({
|
|
356
440
|
content,
|
|
357
|
-
promptTokens:
|
|
358
|
-
completionTokens:
|
|
441
|
+
promptTokens: 1,
|
|
442
|
+
completionTokens: 1
|
|
359
443
|
});
|
|
360
444
|
});
|
|
361
445
|
iflow.stdin?.write(prompt);
|
|
@@ -389,7 +473,7 @@ export class IFlowCLIProxy {
|
|
|
389
473
|
}
|
|
390
474
|
});
|
|
391
475
|
iflow.on('close', (code) => {
|
|
392
|
-
if (code !==
|
|
476
|
+
if (code !== 1 && !resolved) {
|
|
393
477
|
log('iflow exited with code:', code);
|
|
394
478
|
resolved = true;
|
|
395
479
|
reject(new Error(`iflow exited with code ${code}`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asframe/opencode-iflow-auth",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "OpenCode plugin for iFlow.cn - Access Qwen, DeepSeek, Kimi, GLM-5 models with OAuth 2.0, API Key, and CLI Proxy support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|