@tokenaut/opentoken 1.4.10 → 1.4.12
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 +2 -1
- package/package.json +1 -1
- package/src/cli.js +3 -2
- package/src/codex-config.js +6 -4
- package/src/config.js +1 -0
- package/src/test-connection.js +19 -1
- package/src/tools/atomcode.js +8 -7
- package/src/tools/claude.js +95 -15
- package/src/tools/claude_desktop.js +10 -7
- package/src/tools/codex.js +8 -7
- package/src/tools/hermes.js +8 -7
- package/src/tools/openclaw.js +11 -8
- package/src/tools/opencode.js +8 -7
package/README.md
CHANGED
|
@@ -151,7 +151,8 @@ opentoken cx -k <api_key> -u https://gw.opentoken.io/v1 -m <model_id>
|
|
|
151
151
|
验证各工具的 API Key、Base URL、模型是否配置正确,发送最小请求检测连通性:
|
|
152
152
|
|
|
153
153
|
```bash
|
|
154
|
-
opentoken cc test
|
|
154
|
+
opentoken cc test
|
|
155
|
+
opentoken cc test -m <model_id>
|
|
155
156
|
opentoken cdt test
|
|
156
157
|
opentoken ac test
|
|
157
158
|
opentoken hm test
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -102,7 +102,8 @@ function printHelp() {
|
|
|
102
102
|
console.log(' opentoken cdt -k <k> -u <u> 一键设置 Key 与 URL');
|
|
103
103
|
console.log('');
|
|
104
104
|
console.log(chalk.bold('连接测试:'));
|
|
105
|
-
console.log(' opentoken cc test 测试 Claude Code
|
|
105
|
+
console.log(' opentoken cc test 测试 Claude Code 所有模型连接');
|
|
106
|
+
console.log(' opentoken cc test -m <model> 测试 Claude Code 指定模型连接');
|
|
106
107
|
console.log(' opentoken cdt test 测试 Claude Desktop 连接');
|
|
107
108
|
console.log(' opentoken ac test 测试 Atomcode 连接');
|
|
108
109
|
console.log(' opentoken hm test 测试 Hermes 连接');
|
|
@@ -277,7 +278,7 @@ async function run() {
|
|
|
277
278
|
if (args.subcommand === 'test') {
|
|
278
279
|
clearScreen();
|
|
279
280
|
printLogo();
|
|
280
|
-
if (isCcCommand(args.tool)) { await claude.test(); return; }
|
|
281
|
+
if (isCcCommand(args.tool)) { await claude.test({ model: args.model }); return; }
|
|
281
282
|
if (isClaudeDesktopCommand(args.tool)) { await claudeDesktop.test(); return; }
|
|
282
283
|
if (isAtomcodeCommand(args.tool)) { await atomcode.test(); return; }
|
|
283
284
|
if (isHermesCommand(args.tool)) { await hermes.test(); return; }
|
package/src/codex-config.js
CHANGED
|
@@ -93,11 +93,13 @@ function getCurrentCodexConfig() {
|
|
|
93
93
|
data.model_providers && typeof data.model_providers === 'object' && !Array.isArray(data.model_providers)
|
|
94
94
|
? data.model_providers
|
|
95
95
|
: {};
|
|
96
|
+
|
|
97
|
+
const activeKey = data.model_provider != null ? String(data.model_provider) : CODEX_PROVIDER_KEY;
|
|
96
98
|
const provider =
|
|
97
|
-
providers[
|
|
98
|
-
typeof providers[
|
|
99
|
-
!Array.isArray(providers[
|
|
100
|
-
? providers[
|
|
99
|
+
providers[activeKey] &&
|
|
100
|
+
typeof providers[activeKey] === 'object' &&
|
|
101
|
+
!Array.isArray(providers[activeKey])
|
|
102
|
+
? providers[activeKey]
|
|
101
103
|
: {};
|
|
102
104
|
|
|
103
105
|
return {
|
package/src/config.js
CHANGED
package/src/test-connection.js
CHANGED
|
@@ -143,4 +143,22 @@ async function testOpenAIResponses({ baseUrl, apiKey, model }) {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
147
|
+
|
|
148
|
+
async function testWithSpinner({ label, testFn, args }) {
|
|
149
|
+
let frameIdx = 0;
|
|
150
|
+
const spinnerTimer = setInterval(() => {
|
|
151
|
+
const frame = SPINNER_FRAMES[frameIdx % SPINNER_FRAMES.length];
|
|
152
|
+
process.stdout.write('\x1b[1A\x1b[K');
|
|
153
|
+
process.stdout.write('\x1b[36m ' + frame + ' ' + label + ' 测试中...\x1b[0m\n');
|
|
154
|
+
frameIdx++;
|
|
155
|
+
}, 80);
|
|
156
|
+
|
|
157
|
+
const result = await testFn(args);
|
|
158
|
+
clearInterval(spinnerTimer);
|
|
159
|
+
|
|
160
|
+
process.stdout.write('\x1b[1A\x1b[K');
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = { testAnthropic, testOpenAI, testOpenAIResponses, testWithSpinner };
|
package/src/tools/atomcode.js
CHANGED
|
@@ -11,7 +11,7 @@ const {
|
|
|
11
11
|
} = require('../atomcode-config');
|
|
12
12
|
const { printLogo } = require('../logo');
|
|
13
13
|
const { clearScreen } = require('../screen');
|
|
14
|
-
const { testOpenAI } = require('../test-connection');
|
|
14
|
+
const { testOpenAI, testWithSpinner } = require('../test-connection');
|
|
15
15
|
|
|
16
16
|
let pendingConfig = { apiKey: null, model: null };
|
|
17
17
|
|
|
@@ -271,17 +271,18 @@ async function test() {
|
|
|
271
271
|
console.log(chalk.gray(' 模型 : ') + config.model);
|
|
272
272
|
console.log(chalk.gray(' API Key : ') + maskApiKey(config.apiKey));
|
|
273
273
|
console.log('');
|
|
274
|
+
console.log(chalk.gray(' ' + config.model + ' 等待测试'));
|
|
274
275
|
|
|
275
|
-
const result = await
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
model: config.model,
|
|
276
|
+
const result = await testWithSpinner({
|
|
277
|
+
label: config.model,
|
|
278
|
+
testFn: testOpenAI,
|
|
279
|
+
args: { baseUrl: ATOMCODE_OPENTOKEN_BASE_URL, apiKey: config.apiKey, model: config.model },
|
|
279
280
|
});
|
|
280
281
|
|
|
281
282
|
if (result.ok) {
|
|
282
|
-
console.log(chalk.green(' ✓
|
|
283
|
+
console.log(chalk.green(' ✓ ' + config.model + ' 连接成功 ' + result.latency_ms + 'ms'));
|
|
283
284
|
} else {
|
|
284
|
-
console.log(chalk.red(' ✗
|
|
285
|
+
console.log(chalk.red(' ✗ ' + config.model + ' ' + result.error));
|
|
285
286
|
}
|
|
286
287
|
console.log('');
|
|
287
288
|
}
|
package/src/tools/claude.js
CHANGED
|
@@ -4,10 +4,10 @@ const chalk = require('chalk');
|
|
|
4
4
|
const inquirer = require('inquirer');
|
|
5
5
|
const { API_NODES, DEFAULT_BASE_URL, CLAUDE_DEFAULT_MODEL } = require('../models');
|
|
6
6
|
const { fetchModelsForBaseUrl } = require('../fetch-models');
|
|
7
|
-
const { getCurrentConfig, applyConfig } = require('../config');
|
|
7
|
+
const { getCurrentConfig, applyConfig, readClaudeSettings } = require('../config');
|
|
8
8
|
const { printLogo } = require('../logo');
|
|
9
9
|
const { clearScreen } = require('../screen');
|
|
10
|
-
const { testAnthropic } = require('../test-connection');
|
|
10
|
+
const { testAnthropic, testWithSpinner } = require('../test-connection');
|
|
11
11
|
|
|
12
12
|
let pendingConfig = { apiKey: null, baseUrl: null, model: null };
|
|
13
13
|
|
|
@@ -303,7 +303,7 @@ function quickSet({ key, url, model }) {
|
|
|
303
303
|
return true;
|
|
304
304
|
}
|
|
305
305
|
|
|
306
|
-
async function test() {
|
|
306
|
+
async function test({ model } = {}) {
|
|
307
307
|
const config = getCurrentConfig();
|
|
308
308
|
|
|
309
309
|
if (!config.apiKey) {
|
|
@@ -314,29 +314,109 @@ async function test() {
|
|
|
314
314
|
console.log(chalk.red(' ✗ 请先配置 Base URL'));
|
|
315
315
|
return;
|
|
316
316
|
}
|
|
317
|
-
|
|
318
|
-
|
|
317
|
+
|
|
318
|
+
if (model) {
|
|
319
|
+
console.log('');
|
|
320
|
+
console.log(chalk.bold(chalk.cyan('正在测试 Claude Code 连接...')));
|
|
321
|
+
console.log(chalk.gray(' Base URL : ') + config.baseUrl);
|
|
322
|
+
console.log(chalk.gray(' API Key : ') + maskApiKey(config.apiKey));
|
|
323
|
+
console.log('');
|
|
324
|
+
console.log(chalk.gray(' ' + model + ' 等待测试'));
|
|
325
|
+
|
|
326
|
+
const result = await testWithSpinner({
|
|
327
|
+
label: model,
|
|
328
|
+
testFn: testAnthropic,
|
|
329
|
+
args: { baseUrl: config.baseUrl, apiKey: config.apiKey, model },
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
if (result.ok) {
|
|
333
|
+
console.log(chalk.green(' ✓ ' + model + ' 连接成功 ' + result.latency_ms + 'ms'));
|
|
334
|
+
} else {
|
|
335
|
+
console.log(chalk.red(' ✗ ' + model + ' ' + result.error));
|
|
336
|
+
}
|
|
337
|
+
console.log('');
|
|
319
338
|
return;
|
|
320
339
|
}
|
|
321
340
|
|
|
341
|
+
const settings = readClaudeSettings();
|
|
342
|
+
const env = settings.env || {};
|
|
343
|
+
|
|
344
|
+
const modelEntries = [
|
|
345
|
+
{ label: 'Haiku', id: env.ANTHROPIC_DEFAULT_HAIKU_MODEL || 'claude-haiku-4-5' },
|
|
346
|
+
{ label: 'Sonnet', id: env.ANTHROPIC_DEFAULT_SONNET_MODEL || 'claude-sonnet-4-6' },
|
|
347
|
+
{ label: 'Opus', id: env.ANTHROPIC_DEFAULT_OPUS_MODEL || 'claude-opus-4-7' },
|
|
348
|
+
{ label: 'Fable', id: env.ANTHROPIC_DEFAULT_FABLE_MODEL || 'claude-fable-5' },
|
|
349
|
+
];
|
|
350
|
+
|
|
351
|
+
if (config.model && !modelEntries.some((e) => e.id === config.model)) {
|
|
352
|
+
modelEntries.push({ label: '主模型', id: config.model });
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const seen = new Set();
|
|
356
|
+
const unique = [];
|
|
357
|
+
for (const e of modelEntries) {
|
|
358
|
+
if (!seen.has(e.id)) {
|
|
359
|
+
seen.add(e.id);
|
|
360
|
+
unique.push(e);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
365
|
+
const results = new Array(unique.length).fill(null);
|
|
366
|
+
let testingIdx = -1;
|
|
367
|
+
let frameIdx = 0;
|
|
368
|
+
|
|
369
|
+
function renderLines() {
|
|
370
|
+
const lines = unique.map((entry, i) => {
|
|
371
|
+
if (results[i]) {
|
|
372
|
+
return results[i].ok
|
|
373
|
+
? chalk.green(' ✓ ' + entry.label + ' (' + entry.id + ') 连接成功 ' + results[i].latency_ms + 'ms')
|
|
374
|
+
: chalk.red(' ✗ ' + entry.label + ' (' + entry.id + ') ' + results[i].error);
|
|
375
|
+
}
|
|
376
|
+
if (i === testingIdx) {
|
|
377
|
+
const frame = SPINNER_FRAMES[frameIdx % SPINNER_FRAMES.length];
|
|
378
|
+
return chalk.cyan(' ' + frame + ' ' + entry.label + ' (' + entry.id + ') 测试中...');
|
|
379
|
+
}
|
|
380
|
+
return chalk.gray(' ' + entry.label + ' (' + entry.id + ') 等待测试');
|
|
381
|
+
});
|
|
382
|
+
process.stdout.write('\x1b[' + unique.length + 'A\x1b[J');
|
|
383
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
384
|
+
}
|
|
385
|
+
|
|
322
386
|
console.log('');
|
|
323
387
|
console.log(chalk.bold(chalk.cyan('正在测试 Claude Code 连接...')));
|
|
324
388
|
console.log(chalk.gray(' Base URL : ') + config.baseUrl);
|
|
325
|
-
console.log(chalk.gray(' 模型 : ') + config.model);
|
|
326
389
|
console.log(chalk.gray(' API Key : ') + maskApiKey(config.apiKey));
|
|
327
390
|
console.log('');
|
|
328
391
|
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
model: config.model,
|
|
333
|
-
});
|
|
392
|
+
for (const entry of unique) {
|
|
393
|
+
console.log(chalk.gray(' ' + entry.label + ' (' + entry.id + ') 等待测试'));
|
|
394
|
+
}
|
|
334
395
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
396
|
+
for (let i = 0; i < unique.length; i++) {
|
|
397
|
+
testingIdx = i;
|
|
398
|
+
frameIdx = 0;
|
|
399
|
+
|
|
400
|
+
const spinnerTimer = setInterval(() => {
|
|
401
|
+
frameIdx++;
|
|
402
|
+
renderLines();
|
|
403
|
+
}, 80);
|
|
404
|
+
|
|
405
|
+
const result = await testAnthropic({
|
|
406
|
+
baseUrl: config.baseUrl,
|
|
407
|
+
apiKey: config.apiKey,
|
|
408
|
+
model: unique[i].id,
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
clearInterval(spinnerTimer);
|
|
412
|
+
results[i] = result;
|
|
413
|
+
testingIdx = -1;
|
|
414
|
+
renderLines();
|
|
339
415
|
}
|
|
416
|
+
|
|
417
|
+
const okCount = results.filter((r) => r && r.ok).length;
|
|
418
|
+
console.log('');
|
|
419
|
+
console.log(chalk.gray(' ' + okCount + '/' + unique.length + ' 连接成功'));
|
|
340
420
|
console.log('');
|
|
341
421
|
}
|
|
342
422
|
|
|
@@ -6,7 +6,7 @@ const { API_NODES, DEFAULT_BASE_URL } = require('../models');
|
|
|
6
6
|
const { getCurrentConfig, applyConfig } = require('../claude-desktop-config');
|
|
7
7
|
const { printLogo } = require('../logo');
|
|
8
8
|
const { clearScreen } = require('../screen');
|
|
9
|
-
const { testAnthropic } = require('../test-connection');
|
|
9
|
+
const { testAnthropic, testWithSpinner } = require('../test-connection');
|
|
10
10
|
|
|
11
11
|
let pendingConfig = { apiKey: null, baseUrl: null };
|
|
12
12
|
|
|
@@ -197,22 +197,25 @@ async function test() {
|
|
|
197
197
|
return;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
const model = 'claude-sonnet-4-6';
|
|
201
|
+
|
|
200
202
|
console.log('');
|
|
201
203
|
console.log(chalk.bold(chalk.cyan('正在测试 Claude Desktop 连接...')));
|
|
202
204
|
console.log(chalk.gray(' Base URL : ') + config.baseUrl);
|
|
203
205
|
console.log(chalk.gray(' API Key : ') + maskApiKey(config.apiKey));
|
|
204
206
|
console.log('');
|
|
207
|
+
console.log(chalk.gray(' ' + model + ' 等待测试'));
|
|
205
208
|
|
|
206
|
-
const result = await
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
209
|
+
const result = await testWithSpinner({
|
|
210
|
+
label: model,
|
|
211
|
+
testFn: testAnthropic,
|
|
212
|
+
args: { baseUrl: config.baseUrl, apiKey: config.apiKey, model },
|
|
210
213
|
});
|
|
211
214
|
|
|
212
215
|
if (result.ok) {
|
|
213
|
-
console.log(chalk.green(' ✓
|
|
216
|
+
console.log(chalk.green(' ✓ ' + model + ' 连接成功 ' + result.latency_ms + 'ms'));
|
|
214
217
|
} else {
|
|
215
|
-
console.log(chalk.red(' ✗
|
|
218
|
+
console.log(chalk.red(' ✗ ' + model + ' ' + result.error));
|
|
216
219
|
}
|
|
217
220
|
console.log('');
|
|
218
221
|
}
|
package/src/tools/codex.js
CHANGED
|
@@ -12,7 +12,7 @@ const {
|
|
|
12
12
|
} = require('../codex-config');
|
|
13
13
|
const { printLogo } = require('../logo');
|
|
14
14
|
const { clearScreen } = require('../screen');
|
|
15
|
-
const { testOpenAIResponses } = require('../test-connection');
|
|
15
|
+
const { testOpenAIResponses, testWithSpinner } = require('../test-connection');
|
|
16
16
|
|
|
17
17
|
let pendingConfig = { apiKey: null, baseUrl: null, model: null, models: null };
|
|
18
18
|
|
|
@@ -349,17 +349,18 @@ async function test() {
|
|
|
349
349
|
console.log(chalk.gray(' 模型 : ') + config.model);
|
|
350
350
|
console.log(chalk.gray(' API Key : ') + maskApiKey(config.apiKey));
|
|
351
351
|
console.log('');
|
|
352
|
+
console.log(chalk.gray(' ' + config.model + ' 等待测试'));
|
|
352
353
|
|
|
353
|
-
const result = await
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
model: config.model,
|
|
354
|
+
const result = await testWithSpinner({
|
|
355
|
+
label: config.model,
|
|
356
|
+
testFn: testOpenAIResponses,
|
|
357
|
+
args: { baseUrl: config.baseUrl, apiKey: config.apiKey, model: config.model },
|
|
357
358
|
});
|
|
358
359
|
|
|
359
360
|
if (result.ok) {
|
|
360
|
-
console.log(chalk.green(' ✓
|
|
361
|
+
console.log(chalk.green(' ✓ ' + config.model + ' 连接成功 ' + result.latency_ms + 'ms'));
|
|
361
362
|
} else {
|
|
362
|
-
console.log(chalk.red(' ✗
|
|
363
|
+
console.log(chalk.red(' ✗ ' + config.model + ' ' + result.error));
|
|
363
364
|
}
|
|
364
365
|
console.log('');
|
|
365
366
|
}
|
package/src/tools/hermes.js
CHANGED
|
@@ -12,7 +12,7 @@ const {
|
|
|
12
12
|
} = require('../hermes-config');
|
|
13
13
|
const { printLogo } = require('../logo');
|
|
14
14
|
const { clearScreen } = require('../screen');
|
|
15
|
-
const { testOpenAI } = require('../test-connection');
|
|
15
|
+
const { testOpenAI, testWithSpinner } = require('../test-connection');
|
|
16
16
|
|
|
17
17
|
let pendingConfig = { apiKey: null, model: null };
|
|
18
18
|
|
|
@@ -292,17 +292,18 @@ async function test() {
|
|
|
292
292
|
console.log(chalk.gray(' 模型 : ') + config.model);
|
|
293
293
|
console.log(chalk.gray(' API Key : ') + maskApiKey(config.apiKey));
|
|
294
294
|
console.log('');
|
|
295
|
+
console.log(chalk.gray(' ' + config.model + ' 等待测试'));
|
|
295
296
|
|
|
296
|
-
const result = await
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
model: config.model,
|
|
297
|
+
const result = await testWithSpinner({
|
|
298
|
+
label: config.model,
|
|
299
|
+
testFn: testOpenAI,
|
|
300
|
+
args: { baseUrl: HERMES_OPENTOKEN_BASE_URL, apiKey: config.apiKey, model: config.model },
|
|
300
301
|
});
|
|
301
302
|
|
|
302
303
|
if (result.ok) {
|
|
303
|
-
console.log(chalk.green(' ✓
|
|
304
|
+
console.log(chalk.green(' ✓ ' + config.model + ' 连接成功 ' + result.latency_ms + 'ms'));
|
|
304
305
|
} else {
|
|
305
|
-
console.log(chalk.red(' ✗
|
|
306
|
+
console.log(chalk.red(' ✗ ' + config.model + ' ' + result.error));
|
|
306
307
|
}
|
|
307
308
|
console.log('');
|
|
308
309
|
}
|
package/src/tools/openclaw.js
CHANGED
|
@@ -11,7 +11,7 @@ const {
|
|
|
11
11
|
} = require('../openclaw-config');
|
|
12
12
|
const { printLogo } = require('../logo');
|
|
13
13
|
const { clearScreen } = require('../screen');
|
|
14
|
-
const { testOpenAI } = require('../test-connection');
|
|
14
|
+
const { testOpenAI, testWithSpinner } = require('../test-connection');
|
|
15
15
|
|
|
16
16
|
let pendingConfig = { apiKey: null, model: null };
|
|
17
17
|
|
|
@@ -254,23 +254,26 @@ async function test() {
|
|
|
254
254
|
return;
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
+
const modelLabel = OPENCLAW_PROVIDER_KEY + '/' + config.model;
|
|
258
|
+
|
|
257
259
|
console.log('');
|
|
258
260
|
console.log(chalk.bold(chalk.cyan('正在测试 OpenClaw 连接...')));
|
|
259
261
|
console.log(chalk.gray(' Base URL : ') + OPENCLAW_OPENTOKEN_BASE_URL);
|
|
260
|
-
console.log(chalk.gray(' 模型 : ') +
|
|
262
|
+
console.log(chalk.gray(' 模型 : ') + modelLabel);
|
|
261
263
|
console.log(chalk.gray(' API Key : ') + maskApiKey(config.apiKey));
|
|
262
264
|
console.log('');
|
|
265
|
+
console.log(chalk.gray(' ' + modelLabel + ' 等待测试'));
|
|
263
266
|
|
|
264
|
-
const result = await
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
model: config.model,
|
|
267
|
+
const result = await testWithSpinner({
|
|
268
|
+
label: modelLabel,
|
|
269
|
+
testFn: testOpenAI,
|
|
270
|
+
args: { baseUrl: OPENCLAW_OPENTOKEN_BASE_URL, apiKey: config.apiKey, model: config.model },
|
|
268
271
|
});
|
|
269
272
|
|
|
270
273
|
if (result.ok) {
|
|
271
|
-
console.log(chalk.green(' ✓
|
|
274
|
+
console.log(chalk.green(' ✓ ' + modelLabel + ' 连接成功 ' + result.latency_ms + 'ms'));
|
|
272
275
|
} else {
|
|
273
|
-
console.log(chalk.red(' ✗
|
|
276
|
+
console.log(chalk.red(' ✗ ' + modelLabel + ' ' + result.error));
|
|
274
277
|
}
|
|
275
278
|
console.log('');
|
|
276
279
|
}
|
package/src/tools/opencode.js
CHANGED
|
@@ -11,7 +11,7 @@ const {
|
|
|
11
11
|
} = require('../opencode-config');
|
|
12
12
|
const { printLogo } = require('../logo');
|
|
13
13
|
const { clearScreen } = require('../screen');
|
|
14
|
-
const { testOpenAI } = require('../test-connection');
|
|
14
|
+
const { testOpenAI, testWithSpinner } = require('../test-connection');
|
|
15
15
|
|
|
16
16
|
let pendingConfig = { apiKey: null, model: null };
|
|
17
17
|
|
|
@@ -274,17 +274,18 @@ async function test() {
|
|
|
274
274
|
console.log(chalk.gray(' 模型 : ') + config.model);
|
|
275
275
|
console.log(chalk.gray(' API Key : ') + maskApiKey(config.apiKey));
|
|
276
276
|
console.log('');
|
|
277
|
+
console.log(chalk.gray(' ' + config.model + ' 等待测试'));
|
|
277
278
|
|
|
278
|
-
const result = await
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
model: config.model,
|
|
279
|
+
const result = await testWithSpinner({
|
|
280
|
+
label: config.model,
|
|
281
|
+
testFn: testOpenAI,
|
|
282
|
+
args: { baseUrl: OPENCODE_OPENTOKEN_BASE_URL, apiKey: config.apiKey, model: config.model },
|
|
282
283
|
});
|
|
283
284
|
|
|
284
285
|
if (result.ok) {
|
|
285
|
-
console.log(chalk.green(' ✓
|
|
286
|
+
console.log(chalk.green(' ✓ ' + config.model + ' 连接成功 ' + result.latency_ms + 'ms'));
|
|
286
287
|
} else {
|
|
287
|
-
console.log(chalk.red(' ✗
|
|
288
|
+
console.log(chalk.red(' ✗ ' + config.model + ' ' + result.error));
|
|
288
289
|
}
|
|
289
290
|
console.log('');
|
|
290
291
|
}
|