@simonyea/holysheep-cli 1.6.8 → 1.6.9
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 +1 -0
- package/package.json +1 -1
- package/src/tools/droid.js +17 -56
- package/src/tools/openclaw.js +13 -22
package/README.md
CHANGED
|
@@ -218,6 +218,7 @@ A: OpenClaw 需要 Node.js 20+,运行 `node --version` 确认版本后重试
|
|
|
218
218
|
|
|
219
219
|
## Changelog
|
|
220
220
|
|
|
221
|
+
- **v1.6.9** — 保留 OpenClaw 的 MiniMax 配置,并为 MiniMax 使用独立 provider id,避免与 Claude provider 冲突;在 OpenClaw 2026.3.13 下改为提示精确 `/model` 切换命令,而不是停止配置 MiniMax
|
|
221
222
|
- **v1.6.8** — 修复 Codex 重复写入 `config.toml` 导致的 duplicate key,并修复 OpenClaw 在 Windows 下的安装检测;针对 OpenClaw 2026.3.13 的模型路由回归,临时跳过 MiniMax 避免 `model not allowed`
|
|
222
223
|
- **v1.6.7** — OpenClaw 配置新增 `MiniMax-M2.7-highspeed`,并补齐节点迁移脚本中的 SSH 代理账号创建逻辑
|
|
223
224
|
- **v1.6.6** — 修复 Droid CLI 的 GPT-5.4 配置残留问题,同时同步 `~/.factory/settings.json` 和 `~/.factory/config.json`,统一使用 `openai + https://api.holysheep.ai/v1`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simonyea/holysheep-cli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.9",
|
|
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",
|
package/src/tools/droid.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 配置文件: ~/.factory/settings.json
|
|
4
4
|
*
|
|
5
5
|
* 使用 Droid 原生 customModels 配置 HolySheep 的多个模型入口:
|
|
6
|
-
* - GPT 走 OpenAI 兼容入口: https://api.holysheep.ai/
|
|
6
|
+
* - GPT 走 OpenAI 兼容入口: https://api.holysheep.ai/openai
|
|
7
7
|
* - Claude 走 Anthropic 入口: https://api.holysheep.ai
|
|
8
8
|
* - MiniMax 走 Anthropic 入口: https://api.holysheep.ai/minimax
|
|
9
9
|
*/
|
|
@@ -13,13 +13,12 @@ const os = require('os')
|
|
|
13
13
|
|
|
14
14
|
const CONFIG_DIR = path.join(os.homedir(), '.factory')
|
|
15
15
|
const SETTINGS_FILE = path.join(CONFIG_DIR, 'settings.json')
|
|
16
|
-
const LEGACY_CONFIG_FILE = path.join(CONFIG_DIR, 'config.json')
|
|
17
16
|
|
|
18
17
|
const DEFAULT_MODELS = [
|
|
19
18
|
{
|
|
20
19
|
model: 'gpt-5.4',
|
|
21
20
|
id: 'custom:gpt-5.4-0',
|
|
22
|
-
baseUrlSuffix: '',
|
|
21
|
+
baseUrlSuffix: '/openai',
|
|
23
22
|
displayName: 'GPT-5.4',
|
|
24
23
|
provider: 'openai',
|
|
25
24
|
},
|
|
@@ -67,24 +66,6 @@ function writeSettings(data) {
|
|
|
67
66
|
fs.writeFileSync(SETTINGS_FILE, JSON.stringify(data, null, 2), 'utf8')
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
function readLegacyConfig() {
|
|
71
|
-
try {
|
|
72
|
-
if (fs.existsSync(LEGACY_CONFIG_FILE)) {
|
|
73
|
-
return JSON.parse(fs.readFileSync(LEGACY_CONFIG_FILE, 'utf8'))
|
|
74
|
-
}
|
|
75
|
-
} catch {}
|
|
76
|
-
return {}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function writeLegacyConfig(data) {
|
|
80
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true })
|
|
81
|
-
fs.writeFileSync(LEGACY_CONFIG_FILE, JSON.stringify(data, null, 2), 'utf8')
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function isHolySheepModel(item) {
|
|
85
|
-
return typeof item?.baseUrl === 'string' && item.baseUrl.includes('api.holysheep.ai')
|
|
86
|
-
}
|
|
87
|
-
|
|
88
69
|
function normalizeSelectedModels(selectedModels) {
|
|
89
70
|
const selected = new Set(
|
|
90
71
|
Array.isArray(selectedModels) && selectedModels.length > 0
|
|
@@ -103,17 +84,13 @@ function normalizeSelectedModels(selectedModels) {
|
|
|
103
84
|
return models.length > 0 ? models : DEFAULT_MODELS.map((item, index) => ({ ...item, index }))
|
|
104
85
|
}
|
|
105
86
|
|
|
106
|
-
function buildCustomModels(apiKey, baseUrlAnthropic,
|
|
107
|
-
const
|
|
108
|
-
const openaiRootUrl = String(baseUrlOpenAI || '').replace(/\/+$/, '')
|
|
87
|
+
function buildCustomModels(apiKey, baseUrlAnthropic, selectedModels) {
|
|
88
|
+
const rootUrl = String(baseUrlAnthropic || '').replace(/\/+$/, '')
|
|
109
89
|
return normalizeSelectedModels(selectedModels).map((item) => ({
|
|
110
90
|
model: item.model,
|
|
111
91
|
id: item.id,
|
|
112
92
|
index: item.index,
|
|
113
|
-
baseUrl:
|
|
114
|
-
item.provider === 'openai'
|
|
115
|
-
? `${openaiRootUrl}${item.baseUrlSuffix}`
|
|
116
|
-
: `${anthropicRootUrl}${item.baseUrlSuffix}`,
|
|
93
|
+
baseUrl: `${rootUrl}${item.baseUrlSuffix}`,
|
|
117
94
|
apiKey,
|
|
118
95
|
displayName: item.displayName,
|
|
119
96
|
maxOutputTokens: 64000,
|
|
@@ -131,37 +108,25 @@ module.exports = {
|
|
|
131
108
|
isConfigured() {
|
|
132
109
|
const settings = readSettings()
|
|
133
110
|
const customModels = Array.isArray(settings.customModels) ? settings.customModels : []
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const legacyModels = Array.isArray(legacy.customModels) ? legacy.customModels : []
|
|
138
|
-
return legacyModels.some(isHolySheepModel)
|
|
111
|
+
return customModels.some((item) =>
|
|
112
|
+
typeof item.baseUrl === 'string' && item.baseUrl.includes('api.holysheep.ai')
|
|
113
|
+
)
|
|
139
114
|
},
|
|
140
|
-
configure(apiKey, baseUrlAnthropic,
|
|
141
|
-
const nextModels = buildCustomModels(apiKey, baseUrlAnthropic, baseUrlOpenAI, selectedModels)
|
|
142
|
-
|
|
115
|
+
configure(apiKey, baseUrlAnthropic, _baseUrlOpenAI, _primaryModel, selectedModels) {
|
|
143
116
|
const settings = readSettings()
|
|
144
117
|
const preservedModels = Array.isArray(settings.customModels)
|
|
145
|
-
? settings.customModels.filter(
|
|
118
|
+
? settings.customModels.filter(
|
|
119
|
+
(item) => !(typeof item.baseUrl === 'string' && item.baseUrl.includes('api.holysheep.ai'))
|
|
120
|
+
)
|
|
146
121
|
: []
|
|
122
|
+
|
|
147
123
|
settings.customModels = [
|
|
148
|
-
...
|
|
124
|
+
...buildCustomModels(apiKey, baseUrlAnthropic, selectedModels),
|
|
149
125
|
...preservedModels,
|
|
150
126
|
]
|
|
151
127
|
settings.logoAnimation = 'off'
|
|
152
128
|
writeSettings(settings)
|
|
153
129
|
|
|
154
|
-
const legacy = readLegacyConfig()
|
|
155
|
-
const preservedLegacyModels = Array.isArray(legacy.customModels)
|
|
156
|
-
? legacy.customModels.filter((item) => !isHolySheepModel(item))
|
|
157
|
-
: []
|
|
158
|
-
legacy.customModels = [
|
|
159
|
-
...nextModels,
|
|
160
|
-
...preservedLegacyModels,
|
|
161
|
-
]
|
|
162
|
-
legacy.logoAnimation = 'off'
|
|
163
|
-
writeLegacyConfig(legacy)
|
|
164
|
-
|
|
165
130
|
return {
|
|
166
131
|
file: SETTINGS_FILE,
|
|
167
132
|
hot: true,
|
|
@@ -170,15 +135,11 @@ module.exports = {
|
|
|
170
135
|
reset() {
|
|
171
136
|
const settings = readSettings()
|
|
172
137
|
if (Array.isArray(settings.customModels)) {
|
|
173
|
-
settings.customModels = settings.customModels.filter(
|
|
138
|
+
settings.customModels = settings.customModels.filter(
|
|
139
|
+
(item) => !(typeof item.baseUrl === 'string' && item.baseUrl.includes('api.holysheep.ai'))
|
|
140
|
+
)
|
|
174
141
|
}
|
|
175
142
|
writeSettings(settings)
|
|
176
|
-
|
|
177
|
-
const legacy = readLegacyConfig()
|
|
178
|
-
if (Array.isArray(legacy.customModels)) {
|
|
179
|
-
legacy.customModels = legacy.customModels.filter((item) => !isHolySheepModel(item))
|
|
180
|
-
}
|
|
181
|
-
writeLegacyConfig(legacy)
|
|
182
143
|
},
|
|
183
144
|
getConfigPath() { return SETTINGS_FILE },
|
|
184
145
|
hint: '已写入 ~/.factory/settings.json;重启 Droid 后可见 HolySheep 模型列表',
|
package/src/tools/openclaw.js
CHANGED
|
@@ -148,22 +148,12 @@ function isRoutingRegressionVersion(version) {
|
|
|
148
148
|
return OPENCLAW_ROUTING_REGRESSION_VERSION.test(String(version || '').trim())
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
function
|
|
152
|
-
if (!isRoutingRegressionVersion(runtimeVersion)) {
|
|
153
|
-
return
|
|
151
|
+
function getRoutingRegressionWarning(runtimeVersion, minimaxModelRef) {
|
|
152
|
+
if (!isRoutingRegressionVersion(runtimeVersion) || !minimaxModelRef) {
|
|
153
|
+
return ''
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
const filteredModels = originalModels.filter((model) => !model.startsWith('MiniMax-'))
|
|
158
|
-
|
|
159
|
-
if (filteredModels.length === originalModels.length) {
|
|
160
|
-
return { models: selectedModels, warning: '' }
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
models: filteredModels,
|
|
165
|
-
warning: '当前 OpenClaw 2026.3.13 存在 provider 路由回归,已暂时跳过 MiniMax 模型,避免 /model 和网页切换时报 model not allowed。升级 OpenClaw 后可重新运行 hs setup 恢复。',
|
|
166
|
-
}
|
|
156
|
+
return `当前 OpenClaw 2026.3.13 存在 provider 路由回归,但 HolySheep 仍会保留 MiniMax 配置。若网页模型切换失败,请直接输入 /model ${minimaxModelRef},或升级 OpenClaw 后再试。`
|
|
167
157
|
}
|
|
168
158
|
|
|
169
159
|
function readConfig() {
|
|
@@ -293,7 +283,7 @@ function buildManagedPlan(apiKey, baseUrlAnthropic, baseUrlOpenAI, selectedModel
|
|
|
293
283
|
|
|
294
284
|
const openaiProviderName = buildProviderName(baseUrlOpenAI, 'custom-openai')
|
|
295
285
|
const anthropicProviderName = buildProviderName(baseUrlAnthropic, 'custom-anthropic')
|
|
296
|
-
const minimaxProviderName = buildProviderName(`${baseUrlAnthropic.replace(/\/+$/, '')}/minimax`, 'custom-
|
|
286
|
+
const minimaxProviderName = buildProviderName(`${baseUrlAnthropic.replace(/\/+$/, '')}/minimax`, 'custom-minimax')
|
|
297
287
|
|
|
298
288
|
const providers = {
|
|
299
289
|
[openaiProviderName]: {
|
|
@@ -329,6 +319,7 @@ function buildManagedPlan(apiKey, baseUrlAnthropic, baseUrlOpenAI, selectedModel
|
|
|
329
319
|
providers,
|
|
330
320
|
managedModelRefs,
|
|
331
321
|
primaryRef: `${openaiProviderName}/${OPENCLAW_DEFAULT_MODEL}`,
|
|
322
|
+
minimaxRef: minimaxModels[0] ? `${minimaxProviderName}/${minimaxModels[0]}` : '',
|
|
332
323
|
}
|
|
333
324
|
}
|
|
334
325
|
|
|
@@ -485,11 +476,6 @@ module.exports = {
|
|
|
485
476
|
}
|
|
486
477
|
this._lastRuntimeCommand = runtime.command
|
|
487
478
|
|
|
488
|
-
const sanitizedSelection = sanitizeSelectedModelsForRuntime(selectedModels, runtime.version)
|
|
489
|
-
if (sanitizedSelection.warning) {
|
|
490
|
-
console.log(chalk.yellow(` ⚠️ ${sanitizedSelection.warning}`))
|
|
491
|
-
}
|
|
492
|
-
|
|
493
479
|
runOpenClaw(['gateway', 'stop'], { preferNpx: runtime.via === 'npx' })
|
|
494
480
|
|
|
495
481
|
const gatewayPort = findAvailableGatewayPort(DEFAULT_GATEWAY_PORT)
|
|
@@ -530,15 +516,20 @@ module.exports = {
|
|
|
530
516
|
console.log(chalk.yellow(' ⚠️ onboard 失败,使用备用配置...'))
|
|
531
517
|
}
|
|
532
518
|
|
|
533
|
-
writeManagedConfig(
|
|
519
|
+
const plan = writeManagedConfig(
|
|
534
520
|
result.status === 0 ? readConfig() : {},
|
|
535
521
|
apiKey,
|
|
536
522
|
baseUrlAnthropic,
|
|
537
523
|
baseUrlOpenAI,
|
|
538
|
-
|
|
524
|
+
selectedModels,
|
|
539
525
|
gatewayPort,
|
|
540
526
|
)
|
|
541
527
|
|
|
528
|
+
const routingRegressionWarning = getRoutingRegressionWarning(runtime.version, plan.minimaxRef)
|
|
529
|
+
if (routingRegressionWarning) {
|
|
530
|
+
console.log(chalk.yellow(` ⚠️ ${routingRegressionWarning}`))
|
|
531
|
+
}
|
|
532
|
+
|
|
542
533
|
_disableGatewayAuth(runtime.via === 'npx')
|
|
543
534
|
const serviceReady = _installGatewayService(gatewayPort, runtime.via === 'npx')
|
|
544
535
|
|