@simonyea/holysheep-cli 1.7.15 → 1.7.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "1.7.15",
3
+ "version": "1.7.17",
4
4
  "description": "Claude Code/Cursor/Cline API relay for China — ¥1=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
5
5
  "keywords": [
6
6
  "openai-china",
@@ -101,6 +101,7 @@ function printOpenClawDetails(tool, installState, nodeMajor) {
101
101
  const gatewayPort = typeof tool.getGatewayPort === 'function' ? tool.getGatewayPort() : 18789
102
102
  const bridgePort = typeof tool.getBridgePort === 'function' ? tool.getBridgePort() : null
103
103
  const primaryModel = typeof tool.getPrimaryModel === 'function' ? tool.getPrimaryModel() : ''
104
+ const primaryModelRoute = typeof tool.getPrimaryModelRoute === 'function' ? tool.getPrimaryModelRoute() : ''
104
105
  const listeners = typeof tool.getPortListeners === 'function' ? tool.getPortListeners(gatewayPort) : []
105
106
  const foreignListeners = listeners.filter((item) => !String(item.command || '').toLowerCase().includes('openclaw'))
106
107
  const launchAgent = typeof tool.getLaunchAgentDiagnosis === 'function' ? tool.getLaunchAgentDiagnosis() : null
@@ -128,6 +129,13 @@ function printOpenClawDetails(tool, installState, nodeMajor) {
128
129
  })
129
130
  }
130
131
 
132
+ if (primaryModelRoute) {
133
+ details.push({
134
+ level: 'info',
135
+ text: `当前默认模型路由:${primaryModelRoute}`,
136
+ })
137
+ }
138
+
131
139
  if (bridgePort) {
132
140
  details.push({
133
141
  level: 'info',
@@ -135,6 +143,13 @@ function printOpenClawDetails(tool, installState, nodeMajor) {
135
143
  })
136
144
  }
137
145
 
146
+ if (bridgePort && bridgePort === gatewayPort) {
147
+ details.push({
148
+ level: 'warn',
149
+ text: `Bridge 端口和 Gateway 端口都被配置成了 ${gatewayPort};这会让 OpenClaw provider 请求打回 Gateway 自己并触发 404`,
150
+ })
151
+ }
152
+
138
153
  if (launchAgent?.unstable) {
139
154
  details.push({
140
155
  level: 'warn',
@@ -244,6 +244,26 @@ function getConfiguredPrimaryModel(config = readConfig()) {
244
244
  return config?.agents?.defaults?.model?.primary || ''
245
245
  }
246
246
 
247
+ function normalizePrimaryModelRef(ref = getConfiguredPrimaryModel()) {
248
+ const value = String(ref || '')
249
+ const parts = value.split('/')
250
+ return parts[parts.length - 1] || ''
251
+ }
252
+
253
+ function getPrimaryModelRoute(modelRef = getConfiguredPrimaryModel()) {
254
+ const model = normalizePrimaryModelRef(modelRef)
255
+ if (model.startsWith('gpt-')) {
256
+ return 'openai /chat/completions'
257
+ }
258
+ if (model.startsWith('claude-')) {
259
+ return 'anthropic /v1/messages'
260
+ }
261
+ if (model.startsWith('MiniMax-')) {
262
+ return 'minimax /minimax/v1/messages'
263
+ }
264
+ return 'unknown'
265
+ }
266
+
247
267
  function isPortInUse(port) {
248
268
  try {
249
269
  if (isWin) {
@@ -291,9 +311,11 @@ function listPortListeners(port) {
291
311
  }
292
312
  }
293
313
 
294
- function findAvailableGatewayPort(startPort = DEFAULT_GATEWAY_PORT) {
314
+ function findAvailableGatewayPort(startPort = DEFAULT_GATEWAY_PORT, excludedPorts = []) {
315
+ const excluded = new Set((excludedPorts || []).map((value) => Number(value)).filter((value) => Number.isInteger(value) && value > 0))
295
316
  for (let offset = 0; offset < MAX_PORT_SCAN; offset++) {
296
317
  const port = startPort + offset
318
+ if (excluded.has(port)) continue
297
319
  if (!isPortInUse(port)) return port
298
320
  }
299
321
  return null
@@ -596,7 +618,7 @@ module.exports = {
596
618
  }
597
619
  this._lastGatewayPort = gatewayPort
598
620
 
599
- const bridgePort = findAvailableGatewayPort(DEFAULT_BRIDGE_PORT)
621
+ const bridgePort = findAvailableGatewayPort(DEFAULT_BRIDGE_PORT, [gatewayPort])
600
622
  if (!bridgePort) {
601
623
  throw new Error(`找不到可用桥接端口(已检查 ${DEFAULT_BRIDGE_PORT}-${DEFAULT_BRIDGE_PORT + MAX_PORT_SCAN - 1})`)
602
624
  }
@@ -723,6 +745,7 @@ module.exports = {
723
745
  getBridgePort() { return getConfiguredBridgePort() },
724
746
  getGatewayPort() { return getConfiguredGatewayPort() },
725
747
  getPrimaryModel() { return getConfiguredPrimaryModel() },
748
+ getPrimaryModelRoute() { return getPrimaryModelRoute() },
726
749
  getPortListeners(port = getConfiguredGatewayPort()) { return listPortListeners(port) },
727
750
  getLaunchAgentDiagnosis,
728
751
  get hint() {
@@ -11,7 +11,7 @@
11
11
  * "provider": {
12
12
  * "anthropic": {
13
13
  * "options": {
14
- * "baseURL": "https://api.holysheep.ai",
14
+ * "baseURL": "https://api.holysheep.ai/v1",
15
15
  * "apiKey": "cr_xxx"
16
16
  * }
17
17
  * },
@@ -26,6 +26,8 @@
26
26
  *
27
27
  * 安装方式(推荐): brew install anomalyco/tap/opencode
28
28
  * 或: npm i -g opencode-ai@latest
29
+ * 说明:OpenCode 的 anthropic provider 会自行拼接 /messages,
30
+ * 因此这里必须写 /v1 基地址,最终才会落到 /v1/messages。
29
31
  * 官方文档: https://opencode.ai/docs/config
30
32
  */
31
33
  const fs = require('fs')
@@ -88,10 +90,10 @@ module.exports = {
88
90
  // 设置 schema(方便编辑器自动补全)
89
91
  if (!config['$schema']) config['$schema'] = 'https://opencode.ai/config.json'
90
92
 
91
- // 配置 Anthropic provider(Claude 模型)
93
+ // OpenCode anthropic provider 需要 /v1 基地址,否则会打到 /messages 并返回 404。
92
94
  config.provider.anthropic = {
93
95
  options: {
94
- baseURL: baseUrlAnthropicNoV1, // https://api.holysheep.ai ( /v1)
96
+ baseURL: `${String(baseUrlAnthropicNoV1 || '').replace(/\/+$/, '')}/v1`,
95
97
  apiKey,
96
98
  },
97
99
  }