Skip to content

Commit 0d52227

Browse files
author
shixian
committed
fix: bugs
1 parent aadb20d commit 0d52227

File tree

5 files changed

+55
-35
lines changed

5 files changed

+55
-35
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ ccapi -v
4141
初次使用需要设置 Claude Code 的 settings.json 文件路径和自定义API配置文件路径:
4242

4343
```bash
44-
例如:
45-
# 同时设置两个路径
44+
# windows 默认settings.json路径在 C:\Users\Administrator\.claude\settings.json
45+
# mac 默认settings.json路径在 ~/.claude/settings.json
46+
47+
# 示例: mac同时设置两个路径
4648
ccapi set --settings ~/.claude/settings.json --api /Users/4xian/Desktop/api.json5
4749

4850
# 分别设置
@@ -300,8 +302,8 @@ ccapi test -c openrouter
300302

301303
**测试方式说明:**
302304

303-
- **默认方式**:使用接口模拟方式,直接模拟Claude CLI请求头,速度快
304-
- **CLI方式**(`-c` 选项):使用真实的Claude Code CLI环境,准确度最高,但速度较慢(40-50秒
305+
- **默认方式**:使用接口模拟方式,直接模拟Claude CLI请求,速度快,准确性较高(部分厂商只允许在cli中调用,这种时候你可忽略结果,默认为成功)
306+
- **CLI方式**(`-c` 选项):使用真实的Claude Code CLI环境,准确度最高,可能会出现调用各种mcp服务情况,速度较慢(1分钟左右
305307

306308
**配置说明:**
307309

@@ -318,7 +320,6 @@ ccapi test -c openrouter
318320
"testResponse": false
319321
}
320322
```
321-
322323
- 对于数组格式的URL,会测试所有URL地址,数组配置的URL内部不会按延迟排序,保持原有的URL顺序
323324
- 配置按最佳延迟排序,延迟最低的配置排在前面
324325
- 显示每个配置的最优路线(最快的URL地址)

README_EN.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ First-time use requires setting the path to Claude Code's settings.json file and
4242

4343
```bash
4444
Examples:
45-
# Set both paths simultaneously
45+
# windows default path: C:\Users\Administrator\.claude\settings.json
46+
# mac default path: ~/.claude/settings.json
47+
48+
# mac: Set both paths simultaneously
4649
ccapi set --settings ~/.claude/settings.json --api /Users/4xian/Desktop/api.json5
4750

4851
# Set them separately
@@ -322,7 +325,6 @@ ccapi test openrouter -t 2 # Use 2nd Token
322325
"testResponse": false
323326
}
324327
```
325-
326328
- For array format URLs, all URL addresses will be tested, array configuration URLs will not be sorted by latency internally, maintaining original URL order
327329
- Configurations sorted by best latency, lowest latency configurations appear first
328330
- Shows optimal route (fastest URL address) for each configuration

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/commands/set.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ async function setCommand(options) {
2323
const statusIcon = settingsExists ? chalk.green('✓') : chalk.red('✗')
2424
console.log(` settings.json: ${statusIcon} ${chalk.cyan(currentSettingsPath)}`)
2525
if (!settingsExists) {
26-
console.log(` ${chalk.yellow(await t('prompts.WARNING') + ': ' + await t('prompts.FILE_NOT_EXISTS'))}`)
26+
console.log(
27+
` ${chalk.yellow((await t('prompts.WARNING')) + ': ' + (await t('prompts.FILE_NOT_EXISTS')))}`
28+
)
2729
}
2830
} else {
2931
console.log(` settings.json: ${chalk.yellow(await t('prompts.NOT_SET'))}`)
@@ -34,7 +36,9 @@ async function setCommand(options) {
3436
const statusIcon = apiExists ? chalk.green('✓') : chalk.red('✗')
3537
console.log(` api: ${statusIcon} ${chalk.cyan(currentApiPath)}`)
3638
if (!apiExists) {
37-
console.log(` ${chalk.yellow(await t('prompts.WARNING') + ': ' + await t('prompts.FILE_NOT_EXISTS'))}`)
39+
console.log(
40+
` ${chalk.yellow((await t('prompts.WARNING')) + ': ' + (await t('prompts.FILE_NOT_EXISTS')))}`
41+
)
3842
}
3943
} else {
4044
console.log(` api: ${chalk.yellow(await t('prompts.NOT_SET'))}`)
@@ -45,15 +49,16 @@ async function setCommand(options) {
4549
console.log(` ${chalk.cyan('ccapi set --settings <path>')} - ${await t('prompts.SET_SETTINGS_HELP')}`)
4650
console.log(` ${chalk.cyan('ccapi set --api <path>')} - ${await t('prompts.SET_API_HELP')}`)
4751
} catch (error) {
48-
console.error(chalk.red(await t('errors.READ_CONFIG_FAILED') + ':'), error.message)
52+
console.error(chalk.red((await t('errors.READ_CONFIG_FAILED')) + ':'), error.message)
4953
}
5054
return
5155
}
5256

5357
// 验证命令参数
54-
const validation = validateSetCommand(options)
58+
const validation = await validateSetCommand(options)
59+
5560
if (!validation.valid) {
56-
console.error(chalk.red(await t('errors.PARAM_ERROR') + ':'), validation.error)
61+
console.error(chalk.red((await t('errors.PARAM_ERROR')) + ':'), validation.error)
5762
return
5863
}
5964

@@ -63,7 +68,10 @@ async function setCommand(options) {
6368
if (settings) {
6469
// 检查文件是否存在
6570
if (!(await fileExists(settings))) {
66-
console.warn(chalk.yellow(await t('prompts.WARNING') + ':'), await t('setPaths.SETTINGS_FILE_NOT_EXIST', settings))
71+
console.warn(
72+
chalk.yellow((await t('prompts.WARNING')) + ':'),
73+
await t('setPaths.SETTINGS_FILE_NOT_EXIST', settings)
74+
)
6775
console.log(await t('prompts.PATH_SAVED_ENSURE_EXISTS'))
6876
}
6977

@@ -75,7 +83,7 @@ async function setCommand(options) {
7583
if (api) {
7684
// 检查文件是否存在
7785
if (!(await fileExists(api))) {
78-
console.warn(chalk.yellow(await t('prompts.WARNING') + ':'), await t('setPaths.API_FILE_NOT_EXIST', api))
86+
console.warn(chalk.yellow((await t('prompts.WARNING')) + ':'), await t('setPaths.API_FILE_NOT_EXIST', api))
7987
console.log(await t('prompts.PATH_SAVED_ENSURE_EXISTS'))
8088
}
8189

@@ -87,7 +95,7 @@ async function setCommand(options) {
8795
console.log(chalk.blue(await t('success.CONFIG_SAVED')))
8896
results.forEach((result) => console.log(` ${result}`))
8997
} catch (error) {
90-
console.error(chalk.red(await t('errors.SET_FAILED') + ':'), error.message)
98+
console.error(chalk.red((await t('errors.SET_FAILED')) + ':'), error.message)
9199
process.exit(1)
92100
}
93101
}

src/commands/test.js

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,6 @@ async function testApiLatencyWithCurl(url, key, token, model = 'claude-3-5-haiku
196196

197197
// 执行单次测试的内部函数
198198
async function performSingleTest(testModel, attempt = 1) {
199-
200199
try {
201200
const requestBody = {
202201
model: testModel,
@@ -236,7 +235,7 @@ async function testApiLatencyWithCurl(url, key, token, model = 'claude-3-5-haiku
236235
'-H',
237236
`x-api-key: ${key || token}`,
238237
'-H',
239-
`Authorization: Bearer ${token || key}`,
238+
`Authorization: Bearer ${key || token}`,
240239
'-H',
241240
'x-app: cli',
242241
'-H',
@@ -280,8 +279,6 @@ async function testApiLatencyWithCurl(url, key, token, model = 'claude-3-5-haiku
280279
let httpHeaders = ''
281280
let responseBody = ''
282281

283-
// console.log('response', fullResponse);
284-
285282
if (headerBodySplit.length < 2) {
286283
const lineSplit = fullResponse.split('\n\n')
287284
if (lineSplit.length < 2) {
@@ -294,12 +291,14 @@ async function testApiLatencyWithCurl(url, key, token, model = 'claude-3-5-haiku
294291
responseBody = headerBodySplit.slice(1).join('\r\n\r\n')
295292
}
296293

294+
// console.log('httpHeaders', httpHeaders)
295+
// console.log('responseBody', responseBody)
296+
297297
// 检查HTTP状态码
298298
const statusMatch = httpHeaders.match(/HTTP\/[12](?:\.\d)?\s+(\d{3})\s*(.*)/)
299299
const statusCode = statusMatch ? parseInt(statusMatch[1]) : 0
300300
const statusText = statusMatch ? statusMatch[2].trim() : 'Unknown'
301301

302-
// 如果状态码不是2xx,则认为是错误
303302
if (statusCode < 200 || statusCode >= 300) {
304303
let errorMessage = `HTTP ${statusCode} ${statusText}`
305304

@@ -310,7 +309,6 @@ async function testApiLatencyWithCurl(url, key, token, model = 'claude-3-5-haiku
310309
errorMessage = errorJson.error.message
311310
}
312311
} catch (e) {
313-
// 如果不是JSON,检查是否包含中文错误信息
314312
const cleanBody = responseBody.replace(/<[^>]*>/g, '').trim()
315313
if (cleanBody && cleanBody.length < 200) {
316314
errorMessage = cleanBody
@@ -325,14 +323,24 @@ async function testApiLatencyWithCurl(url, key, token, model = 'claude-3-5-haiku
325323

326324
if (!isEventStream) {
327325
// 非SSE响应,尝试解析为JSON
328-
const jsonResponse = JSON.parse(responseBody.trim())
326+
try {
327+
const jsonResponse = JSON.parse(responseBody.trim())
329328

330-
if (jsonResponse.error) {
331-
throw new Error(jsonResponse.error.message || 'API Error')
332-
}
333-
// 如果是成功的JSON响应,提取内容
334-
if (jsonResponse.content && Array.isArray(jsonResponse.content)) {
335-
responseText = jsonResponse.content.map((c) => c.text).join('')
329+
if (jsonResponse.error) {
330+
throw new Error(jsonResponse.error.message || 'API Error')
331+
}
332+
// 如果是成功的JSON响应,提取内容
333+
if (jsonResponse.content && Array.isArray(jsonResponse.content)) {
334+
responseText = jsonResponse.content.map((c) => c.text).join('')
335+
}
336+
} catch (parseError) {
337+
const errorIndex = responseBody.indexOf('error')
338+
if (errorIndex !== -1) {
339+
const errorPart = responseBody.substring(errorIndex).replace(/\n/g, '').trim()
340+
throw new Error(errorPart)
341+
} else {
342+
throw new Error(responseBody.replace(/\n/g, '').trim() || 'Invalid response format')
343+
}
336344
}
337345
} else {
338346
// SSE响应处理
@@ -386,19 +394,21 @@ async function testApiLatencyWithCurl(url, key, token, model = 'claude-3-5-haiku
386394
return {
387395
success: true,
388396
latency: testLatency,
389-
response: responseText.length > maxText ? responseText.slice(0, maxText) + '...' : responseText.trim(),
397+
response:
398+
responseText.length > maxText
399+
? responseText.slice(0, maxText) + '...'
400+
: responseText.replace(/\n/g, '').trim(),
390401
error: null,
391402
model: testModel,
392403
attempt
393404
}
394-
395405
} catch (error) {
396-
console.log(`Attempt ${attempt} failed:`, error.message)
406+
// console.log(`Attempt ${attempt} failed:`, error.message)
397407

398408
return {
399409
success: false,
400410
latency: 'error',
401-
error: error.message,
411+
error: error.message.replace(/\n/g, '').trim(),
402412
response: null,
403413
model: testModel,
404414
attempt
@@ -429,7 +439,6 @@ async function testApiLatencyWithCurl(url, key, token, model = 'claude-3-5-haiku
429439
return {
430440
...result
431441
}
432-
433442
} catch (error) {
434443
let message = await t('test.REQUEST_FAILED')
435444

@@ -490,7 +499,7 @@ async function testApiLatency(url, key, token, model = 'claude-3-5-haiku-2024102
490499
mcpConfigPath
491500
]
492501

493-
const timeout = configData.testTimeout || 60000
502+
const timeout = configData.testTimeout || 100000
494503
const spawnOptions = {
495504
cwd: tempWorkDir,
496505
stdio: ['pipe', 'pipe', 'pipe']

0 commit comments

Comments
 (0)