@simonyea/holysheep-cli 1.7.15 → 1.7.16

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 CHANGED
@@ -73,6 +73,7 @@ You'll be prompted for your API Key (`cr_xxx`), then select the tools to configu
73
73
  4. Open the exact dashboard URL shown in the terminal and start chatting — do not use a blank browser shell or `about:blank`
74
74
 
75
75
  **Default OpenClaw model:** `gpt-5.4`
76
+ HolySheep keeps GPT as the OpenClaw primary model by default and leaves Claude models available for manual switching inside OpenClaw.
76
77
 
77
78
  > **Keep the gateway window open** while using OpenClaw. The gateway must be running for the browser UI to work.
78
79
  > If only `npx openclaw` is available, HolySheep will start Gateway as a direct process and will not install a persistent daemon from a temporary `npx` cache path.
@@ -162,6 +163,7 @@ hs setup
162
163
  4. 按终端里显示的准确 dashboard 地址打开浏览器,直接开始聊天,不要打开空白浏览器壳窗口或 `about:blank`
163
164
 
164
165
  **OpenClaw 默认模型:** `gpt-5.4`
166
+ HolySheep 会默认把 GPT 设为 OpenClaw 主模型,同时保留 Claude 模型供你在 OpenClaw 内手动切换。
165
167
 
166
168
  > ⚠️ **保持 Gateway 窗口开启**,关闭后 Gateway 停止,浏览器界面无法使用。
167
169
  > 如果机器上只有 `npx openclaw`,HolySheep 会直接启动 Gateway 进程,不会把 daemon 安装到临时 `npx` 缓存路径上。
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.16",
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',
@@ -82,6 +82,19 @@ function getPreferredLaunchCmd(tool) {
82
82
  return tool.launchCmd.replace(/^hs\b/, prefix)
83
83
  }
84
84
 
85
+ function pickPrimaryModelForTool(tool, selectedModels) {
86
+ const models = Array.isArray(selectedModels) ? selectedModels : []
87
+ const fallback = models[0] || 'gpt-5.4'
88
+
89
+ if (tool?.id === 'openclaw') {
90
+ return models.find((m) => m === 'gpt-5.4')
91
+ || models.find((m) => m.startsWith('gpt-'))
92
+ || fallback
93
+ }
94
+
95
+ return models.find((m) => m.startsWith('claude-')) || fallback
96
+ }
97
+
85
98
  function canAutoInstall(toolId) {
86
99
  return !!AUTO_INSTALL[toolId]
87
100
  }
@@ -199,7 +212,6 @@ async function setup(options) {
199
212
  choices: MODEL_CHOICES,
200
213
  pageSize: 5,
201
214
  }])
202
- const primaryModel = selectedModels.find(m => m.startsWith('claude-')) || selectedModels[0] || 'claude-sonnet-4-6'
203
215
 
204
216
  // Step 2: 选择工具(已安装 + 未安装分组显示)
205
217
  const installedTools = TOOLS.filter(t => t.checkInstalled())
@@ -292,6 +304,7 @@ async function setup(options) {
292
304
  for (const tool of toConfigureTools) {
293
305
  const spinner = ora(`配置 ${tool.name}...`).start()
294
306
  try {
307
+ const primaryModel = pickPrimaryModelForTool(tool, selectedModels)
295
308
  const result = tool.configure(apiKey, BASE_URL_ANTHROPIC, BASE_URL_OPENAI, primaryModel, selectedModels)
296
309
 
297
310
  if (result.manual) {
@@ -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) {
@@ -723,6 +743,7 @@ module.exports = {
723
743
  getBridgePort() { return getConfiguredBridgePort() },
724
744
  getGatewayPort() { return getConfiguredGatewayPort() },
725
745
  getPrimaryModel() { return getConfiguredPrimaryModel() },
746
+ getPrimaryModelRoute() { return getPrimaryModelRoute() },
726
747
  getPortListeners(port = getConfiguredGatewayPort()) { return listPortListeners(port) },
727
748
  getLaunchAgentDiagnosis,
728
749
  get hint() {