fix: set authHeader: true by default for MiniMax API provider (#27622)

* Update onboard-auth.config-minimax.ts

fix issue #27600

* fix(minimax): default authHeader for implicit + onboarding providers (#27600)

Landed from contributor PR #27622 by @riccoyuanft and PR #27631 by @kevinWangSheng.
Includes a small TS nullability guard in lane delivery to keep build green on rebased head.

Co-authored-by: riccoyuanft <riccoyuan@gmail.com>
Co-authored-by: Kevin Shenghui <shenghuikevin@github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Kevin Shenghui <shenghuikevin@github.com>
This commit is contained in:
riccoyuanft
2026-02-26 23:53:51 +08:00
committed by GitHub
parent 1708b11fab
commit 60bb475355
6 changed files with 45 additions and 5 deletions

View File

@@ -15,6 +15,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Models/MiniMax auth header defaults: set `authHeader: true` for both onboarding-generated MiniMax API providers and implicit built-in MiniMax (`minimax`, `minimax-portal`) provider templates so first requests no longer fail with MiniMax `401 authentication_error` due to missing `Authorization` header. Landed from contributor PRs #27622 by @riccoyuanft and #27631 by @kevinWangSheng. (#27600, #15303)
- Pi image-token usage: stop re-injecting history image blocks each turn, process image references from the current prompt only, and prune already-answered user-image blocks in stored history to prevent runaway token growth. (#27602)
- BlueBubbles/SSRF: auto-allowlist the configured `serverUrl` hostname for attachment fetches so localhost/private-IP BlueBubbles setups are no longer false-blocked by default SSRF checks. Landed from contributor PR #27648 by @lailoo. (#27599) Thanks @taylorhou for reporting.
- Security/Gateway node pairing: pin paired-device `platform`/`deviceFamily` metadata across reconnects and bind those fields into device-auth signatures, so reconnect metadata spoofing cannot expand node command allowlists without explicit repair pairing. This ships in the next npm release (`2026.2.26`). Thanks @76embiid21 for reporting.

View File

@@ -1,4 +1,5 @@
import { mkdtempSync } from "node:fs";
import { writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
@@ -54,9 +55,38 @@ describe("MiniMax implicit provider (#15275)", () => {
const providers = await resolveImplicitProviders({ agentDir });
expect(providers?.minimax).toBeDefined();
expect(providers?.minimax?.api).toBe("anthropic-messages");
expect(providers?.minimax?.authHeader).toBe(true);
expect(providers?.minimax?.baseUrl).toBe("https://api.minimax.io/anthropic");
});
});
it("should set authHeader for minimax portal provider", async () => {
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
await writeFile(
join(agentDir, "auth-profiles.json"),
JSON.stringify(
{
version: 1,
profiles: {
"minimax-portal:default": {
type: "oauth",
provider: "minimax-portal",
oauth: {
access: "token",
expires: Date.now() + 60_000,
},
},
},
},
null,
2,
),
"utf8",
);
const providers = await resolveImplicitProviders({ agentDir });
expect(providers?.["minimax-portal"]?.authHeader).toBe(true);
});
});
describe("vLLM provider", () => {

View File

@@ -480,6 +480,7 @@ function buildMinimaxProvider(): ProviderConfig {
return {
baseUrl: MINIMAX_PORTAL_BASE_URL,
api: "anthropic-messages",
authHeader: true,
models: [
buildMinimaxTextModel({
id: MINIMAX_DEFAULT_MODEL_ID,
@@ -515,6 +516,7 @@ function buildMinimaxPortalProvider(): ProviderConfig {
return {
baseUrl: MINIMAX_PORTAL_BASE_URL,
api: "anthropic-messages",
authHeader: true,
models: [
buildMinimaxTextModel({
id: MINIMAX_DEFAULT_MODEL_ID,

View File

@@ -181,6 +181,7 @@ function applyMinimaxApiProviderConfigWithBaseUrl(
...existingProviderRest,
baseUrl: params.baseUrl,
api: "anthropic-messages",
authHeader: true,
...(normalizedApiKey?.trim() ? { apiKey: normalizedApiKey } : {}),
models: mergedModels.length > 0 ? mergedModels : [apiModel],
};

View File

@@ -365,6 +365,7 @@ describe("applyMinimaxApiConfig", () => {
expect(cfg.models?.providers?.minimax).toMatchObject({
baseUrl: "https://api.minimax.io/anthropic",
api: "anthropic-messages",
authHeader: true,
});
});
@@ -404,6 +405,7 @@ describe("applyMinimaxApiConfig", () => {
);
expect(cfg.models?.providers?.minimax?.baseUrl).toBe("https://api.minimax.io/anthropic");
expect(cfg.models?.providers?.minimax?.api).toBe("anthropic-messages");
expect(cfg.models?.providers?.minimax?.authHeader).toBe(true);
expect(cfg.models?.providers?.minimax?.apiKey).toBe("old-key");
expect(cfg.models?.providers?.minimax?.models.map((m) => m.id)).toEqual([
"old-model",

View File

@@ -109,11 +109,15 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
text: string;
skipRegressive: "always" | "existingOnly";
hadPreviewMessage: boolean;
}): boolean =>
Boolean(args.currentPreviewText) &&
args.currentPreviewText.startsWith(args.text) &&
args.text.length < args.currentPreviewText.length &&
(args.skipRegressive === "always" || args.hadPreviewMessage);
}): boolean => {
const currentPreviewText = args.currentPreviewText;
return (
currentPreviewText !== undefined &&
currentPreviewText.startsWith(args.text) &&
args.text.length < currentPreviewText.length &&
(args.skipRegressive === "always" || args.hadPreviewMessage)
);
};
const tryEditPreviewMessage = async (args: {
laneName: LaneName;