Skip to content

Commit 461e61f

Browse files
committed
fix(models): set authHeader for third-party anthropic-messages (MiniMax 401)
Match OpenClaw minimax onboard: authHeader true for non-api.anthropic.com hosts. Migrate existing openclaw.json on load; extend seeds (synthetic, opencode, kimi-coding, cloudflare). Release v0.3.4 Made-with: Cursor
1 parent c1fc88c commit 461e61f

8 files changed

Lines changed: 88 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to OpenClaw Desktop will be documented in this file.
44

5+
## [0.3.4] - 2026-03-26
6+
7+
### Fixed
8+
9+
- **MiniMax / third-party Anthropic HTTP 401:** Aligned with OpenClaw `extensions/minimax/onboard.ts` by setting **`authHeader: true`** on `anthropic-messages` providers that target non-`api.anthropic.com` hosts (MiniMax, Synthetic, OpenCode Zen, Kimi Coding, Cloudflare AI Gateway). Existing `openclaw.json` entries are migrated on load. Custom Anthropic-compatible bases get the same flag when the URL is not Anthropic’s official API.
10+
511
## [0.3.3] - 2026-03-26
612

713
### Fixed

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,17 @@ If you've been searching for *how to install OpenClaw on Windows*, *how to run O
4848
## Quick Start
4949

5050
1. Download the latest installer from [Releases](https://github.com/agentkernel/openclaw-desktop/releases/latest)
51-
2. Run `OpenClaw-Setup-0.3.3.exe`
51+
2. Run `OpenClaw-Setup-0.3.4.exe`
5252
3. Finish the setup wizard (provider → channel → gateway)
5353
4. Launch from Start Menu or Desktop shortcut
5454

5555
**System:** Windows 10/11 x64 · ~350 MB free space · Internet for API calls
5656

57-
## What's New in v0.3.3
57+
## What's New in v0.3.4
5858

59-
- **MiniMax (401):** Auth profile id for API keys is **`minimax:global`** (same as the wizard and upstream). The LLM API path no longer maps `default` to `minimax:default`; it is normalized to **`minimax:global`**, and existing `minimax:default` entries in `auth-profiles.json` migrate on startup.
59+
- **MiniMax / Anthropic-compatible 401:** `models.providers.*` now sets **`authHeader: true`** for third-party `anthropic-messages` hosts (same as OpenClaw `extensions/minimax/onboard.ts`). Existing configs are migrated on startup—fixes invalid API key errors when the key is correct but auth headers did not match the host.
60+
61+
Earlier highlights (v0.3.3): `minimax:global` profile id + auth-profiles migration.
6062

6163
Earlier highlights (v0.3.2): Full profile ids for save/migrate/delete; `auth.order` normalization; delete passes `provider`.
6264

@@ -124,8 +126,8 @@ OpenClaw Desktop is a **community-maintained Windows distribution** for the Open
124126

125127
| | |
126128
|---|---|
127-
| **Release** | `v0.3.3` |
128-
| **Installer** | `OpenClaw-Setup-0.3.3.exe` |
129+
| **Release** | `v0.3.4` |
130+
| **Installer** | `OpenClaw-Setup-0.3.4.exe` |
129131
| **Platform** | Windows 10/11 x64 |
130132
| **Includes** | Electron shell, portable Node.js, bundled OpenClaw |
131133
| **Extras** | SHA-256 checksum, `latest.yml` for in-app updates |
@@ -206,7 +208,7 @@ pnpm run prepare-bundle
206208
pnpm run package:win # Output: dist/OpenClaw-Setup-<version>.exe
207209
```
208210

209-
**Bundled OpenClaw:** Pinned in `package.json` (`openclawBundleVersion`). After `prepare-bundle`, see `bundledOpenClawVersion` in [`resources/bundle-manifest.json`](resources/bundle-manifest.json) (currently **2026.3.23-2** for desktop **v0.3.3**). Local checks: `pnpm run check-openclaw-versions` (omit `OPENCLAW_SKIP_NPM_LATEST_CHECK` to also compare against npm `latest`).
211+
**Bundled OpenClaw:** Pinned in `package.json` (`openclawBundleVersion`). After `prepare-bundle`, see `bundledOpenClawVersion` in [`resources/bundle-manifest.json`](resources/bundle-manifest.json) (currently **2026.3.23-2** for desktop **v0.3.4**). Local checks: `pnpm run check-openclaw-versions` (omit `OPENCLAW_SKIP_NPM_LATEST_CHECK` to also compare against npm `latest`).
210212

211213
**Related docs:** [CHANGELOG.md](CHANGELOG.md) · [CONTRIBUTING.md](CONTRIBUTING.md)
212214

README.zh-CN.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,17 @@
4848
## 快速开始
4949

5050
1.[Releases](https://github.com/agentkernel/openclaw-desktop/releases/latest) 下载最新安装包
51-
2. 运行 `OpenClaw-Setup-0.3.3.exe`
51+
2. 运行 `OpenClaw-Setup-0.3.4.exe`
5252
3. 完成设置向导(模型提供商 → 频道 → 网关)
5353
4. 从开始菜单或桌面快捷方式启动
5454

5555
**系统要求:** Windows 10/11 x64 · 约 350 MB 可用空间 · 网络连接(用于 API 调用)
5656

57-
## v0.3.3 更新亮点
57+
## v0.3.4 更新亮点
5858

59-
- **MiniMax(401):** API Key 凭据与向导一致,使用 **`minimax:global`**;不再将 `default` 误规范为 `minimax:default`。启动时会将旧的 `minimax:default` 条目迁移到 `minimax:global`
59+
- **MiniMax / Anthropic 兼容 401:** 与 OpenClaw 上游一致,为第三方 **`anthropic-messages`** 端点设置 **`authHeader: true`**;启动时自动迁移已有 `openclaw.json`。密钥正确但仍报 invalid api key 时多属此类问题。
60+
61+
更早版本(v0.3.3)要点:`minimax:global` 与 auth-profiles 迁移 — 详见 [CHANGELOG.md](CHANGELOG.md)
6062

6163
更早版本(v0.3.2)要点:完整 profile id 的保存/迁移/删除与 `auth.order` 规范化 — 详见 [CHANGELOG.md](CHANGELOG.md)
6264

@@ -124,8 +126,8 @@ OpenClaw Desktop 是 OpenClaw 生态的**社区维护 Windows 分发版**,属
124126

125127
| | |
126128
|---|---|
127-
| **当前版本** | `v0.3.3` |
128-
| **安装包** | `OpenClaw-Setup-0.3.3.exe` |
129+
| **当前版本** | `v0.3.4` |
130+
| **安装包** | `OpenClaw-Setup-0.3.4.exe` |
129131
| **适用系统** | Windows 10/11 x64 |
130132
| **包含内容** | Electron 外壳、便携 Node.js、捆绑 OpenClaw |
131133
| **附加产物** | SHA-256 校验文件、`latest.yml`(应用内更新用) |
@@ -154,7 +156,7 @@ OpenClaw Desktop 是 OpenClaw 生态的**社区维护 Windows 分发版**,属
154156
<details>
155157
<summary><strong>如何在 Windows 上安装 OpenClaw?</strong></summary>
156158

157-
[最新发布页](https://github.com/agentkernel/openclaw-desktop/releases/latest)下载 `OpenClaw-Setup-0.3.3.exe` 并运行即可。无需 `npm`、无需系统级 Node.js、无需输入任何终端命令。
159+
[最新发布页](https://github.com/agentkernel/openclaw-desktop/releases/latest)下载 `OpenClaw-Setup-0.3.4.exe` 并运行即可。无需 `npm`、无需系统级 Node.js、无需输入任何终端命令。
158160
</details>
159161

160162
<details>
@@ -206,7 +208,7 @@ pnpm run prepare-bundle
206208
pnpm run package:win # 输出: dist/OpenClaw-Setup-<version>.exe
207209
```
208210

209-
**捆绑 OpenClaw:**`package.json` 中通过 `openclawBundleVersion` 固定;执行 `prepare-bundle` 后查看 [`resources/bundle-manifest.json`](resources/bundle-manifest.json) 中的 `bundledOpenClawVersion`(桌面 **v0.3.3** 当前为 **2026.3.23-2**)。本地校验:`pnpm run check-openclaw-versions`(不设 `OPENCLAW_SKIP_NPM_LATEST_CHECK` 时还会与 npm `latest` 对比)。
211+
**捆绑 OpenClaw:**`package.json` 中通过 `openclawBundleVersion` 固定;执行 `prepare-bundle` 后查看 [`resources/bundle-manifest.json`](resources/bundle-manifest.json) 中的 `bundledOpenClawVersion`(桌面 **v0.3.4** 当前为 **2026.3.23-2**)。本地校验:`pnpm run check-openclaw-versions`(不设 `OPENCLAW_SKIP_NPM_LATEST_CHECK` 时还会与 npm `latest` 对比)。
210212

211213
**相关文档:** [CHANGELOG.md](CHANGELOG.md) · [CONTRIBUTING.md](CONTRIBUTING.md)
212214

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openclaw-desktop",
3-
"version": "0.3.3",
3+
"version": "0.3.4",
44
"openclawBundleVersion": "2026.3.23-2",
55
"description": "Community-maintained Windows desktop app and installer for OpenClaw.",
66
"type": "module",

resources/bundle-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"shellVersion": "0.3.3",
2+
"shellVersion": "0.3.4",
33
"bundledOpenClawVersion": "2026.3.23-2"
44
}

src/main/config/openclaw-config.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,42 @@ function migrateAuthOrderFullProfileIds(
171171
return { config: next, changed: true }
172172
}
173173

174+
/**
175+
* OpenClaw `extensions/minimax/onboard.ts` sets `authHeader: true` for third-party Anthropic-compatible
176+
* APIs (MiniMax, Synthetic, etc.). Without it, gateways can get HTTP 401 from hosts that expect
177+
* Bearer-style auth (see upstream issue #29169). Only set when missing; do not override explicit values.
178+
*/
179+
function migrateAnthropicThirdPartyAuthHeader(
180+
config: OpenClawConfig,
181+
): { config: OpenClawConfig; changed: boolean } {
182+
const providers = config.models?.providers
183+
if (!providers || typeof providers !== 'object') {
184+
return { config, changed: false }
185+
}
186+
let changed = false
187+
const next = JSON.parse(JSON.stringify(config)) as OpenClawConfig
188+
const nextProviders = next.models?.providers
189+
if (!nextProviders || typeof nextProviders !== 'object') {
190+
return { config, changed: false }
191+
}
192+
193+
for (const [, raw] of Object.entries(nextProviders)) {
194+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) continue
195+
const p = raw as Record<string, unknown>
196+
if (p.authHeader !== undefined) continue
197+
const api = typeof p.api === 'string' ? p.api : ''
198+
if (api !== 'anthropic-messages') continue
199+
const baseUrl = typeof p.baseUrl === 'string' ? p.baseUrl : ''
200+
if (!baseUrl.trim()) continue
201+
if (baseUrl.includes('api.anthropic.com')) continue
202+
p.authHeader = true
203+
changed = true
204+
}
205+
206+
if (!changed) return { config, changed: false }
207+
return { config: next, changed: true }
208+
}
209+
174210
/**
175211
* OpenClaw 2026.1.29+: gateway auth mode `none` removed — gateway must use token or password.
176212
* Migrate legacy `mode: "none"` using whichever credential field is present.
@@ -331,13 +367,16 @@ export function readOpenClawConfig(): OpenClawConfig {
331367
cfg = migratedAuthNone.config
332368
const migratedAuthOrder = migrateAuthOrderFullProfileIds(cfg)
333369
cfg = migratedAuthOrder.config
370+
const migratedAuthHeader = migrateAnthropicThirdPartyAuthHeader(cfg)
371+
cfg = migratedAuthHeader.config
334372
if (
335373
migratedProviders.changed ||
336374
migratedFeishu.changed ||
337375
migratedControlUiRoot.changed ||
338376
migratedControlUi.changed ||
339377
migratedAuthNone.changed ||
340-
migratedAuthOrder.changed
378+
migratedAuthOrder.changed ||
379+
migratedAuthHeader.changed
341380
) {
342381
try {
343382
writeOpenClawConfig(cfg)
@@ -363,6 +402,11 @@ export function readOpenClawConfig(): OpenClawConfig {
363402
if (migratedAuthOrder.changed) {
364403
console.info('[config] Normalized auth.order profile ids to full form (provider:name) in openclaw.json')
365404
}
405+
if (migratedAuthHeader.changed) {
406+
console.info(
407+
'[config] Set models.providers.*.authHeader=true for third-party anthropic-messages hosts in openclaw.json',
408+
)
409+
}
366410
} catch (err) {
367411
console.warn(
368412
'[config] Failed to persist migrated openclaw config:',

src/main/wizard/setup-handler.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ type ProviderSeed = {
4747
baseUrl: string
4848
/** OpenClaw `models.providers.*.api`; omit for plugin-native providers (e.g. Google Gemini). */
4949
api?: string
50+
/**
51+
* Third-party Anthropic-compatible hosts need `authHeader: true` so the gateway sends the same
52+
* auth as upstream `applyMinimaxApiConfig` / OpenClaw issue #29169 (MiniMax 401 without Bearer).
53+
*/
54+
authHeader?: boolean
5055
}
5156

5257
const PROVIDER_SEEDS: Partial<Record<ModelProvider, ProviderSeed>> = {
@@ -79,6 +84,7 @@ const PROVIDER_SEEDS: Partial<Record<ModelProvider, ProviderSeed>> = {
7984
providerId: 'opencode',
8085
baseUrl: 'https://opencode.ai/zen/v1',
8186
api: 'anthropic-messages',
87+
authHeader: true,
8288
},
8389
'vercel-ai-gateway': {
8490
providerId: 'vercel-ai-gateway',
@@ -94,11 +100,13 @@ const PROVIDER_SEEDS: Partial<Record<ModelProvider, ProviderSeed>> = {
94100
providerId: 'kimi-coding',
95101
baseUrl: 'https://api.kimi.com/coding/',
96102
api: 'anthropic-messages',
103+
authHeader: true,
97104
},
98105
minimax: {
99106
providerId: 'minimax',
100107
baseUrl: 'https://api.minimax.io/anthropic',
101108
api: 'anthropic-messages',
109+
authHeader: true,
102110
},
103111
xai: {
104112
providerId: 'xai',
@@ -124,6 +132,7 @@ const PROVIDER_SEEDS: Partial<Record<ModelProvider, ProviderSeed>> = {
124132
providerId: 'synthetic',
125133
baseUrl: 'https://api.synthetic.new/anthropic',
126134
api: 'anthropic-messages',
135+
authHeader: true,
127136
},
128137
venice: {
129138
providerId: 'venice',
@@ -310,6 +319,7 @@ function ensureProviderSeedConfig(config: OpenClawConfig, state: WizardState): v
310319
...(config.models.providers['cloudflare-ai-gateway'] ?? {}),
311320
baseUrl: `https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/anthropic`,
312321
api: 'anthropic-messages',
322+
authHeader: true,
313323
...(state.modelConfig.apiKey.trim() ? { apiKey: state.modelConfig.apiKey.trim() } : {}),
314324
models: [buildDefaultProviderModel(modelId)],
315325
}
@@ -400,6 +410,7 @@ function ensureProviderSeedConfig(config: OpenClawConfig, state: WizardState): v
400410
baseUrl: seed.baseUrl,
401411
...(seed.api ? { api: seed.api } : {}),
402412
...(apiKey ? { apiKey } : {}),
413+
...(seed.authHeader !== undefined ? { authHeader: seed.authHeader } : {}),
403414
models: [buildDefaultProviderModel(modelId)],
404415
}
405416
}
@@ -478,13 +489,16 @@ function buildOpenClawConfig(state: WizardState): OpenClawConfig {
478489
const compatibility = state.modelConfig.customCompatibility ?? 'openai'
479490
const api = compatibility === 'anthropic' ? 'anthropic-messages' : 'openai-completions'
480491
if (baseUrl) {
492+
const thirdPartyAnthropic =
493+
compatibility === 'anthropic' && !baseUrl.includes('api.anthropic.com')
481494
config.models = {
482495
mode: 'merge',
483496
providers: {
484497
[providerId]: {
485498
baseUrl,
486499
api,
487500
apiKey: state.modelConfig.apiKey.trim(),
501+
...(thirdPartyAnthropic ? { authHeader: true } : {}),
488502
models: [buildDefaultProviderModel(modelId || 'default')],
489503
},
490504
},

src/shared/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,10 @@ export interface ModelProviderConfig {
212212
apiKey?: string
213213
/** Custom HTTP headers */
214214
headers?: Record<string, string>
215-
/** Whether to send Authorization (false for local proxies like copilot-proxy) */
215+
/**
216+
* Third-party `anthropic-messages` hosts (MiniMax, Synthetic, Cloudflare gateway, etc.) need `true`
217+
* so the gateway matches OpenClaw upstream onboard configs. Use `false` for local proxies (e.g. copilot-proxy).
218+
*/
216219
authHeader?: boolean
217220
models?: Array<Record<string, unknown> & { id: string; name?: string }>
218221
}

0 commit comments

Comments
 (0)