fix(minimax): ignore blank environment API key (#108777)

* fix(minimax): ignore blank environment API key

* fix(minimax): centralize TTS API key resolution

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
sunlit-deng
2026-07-16 20:26:33 +08:00
committed by GitHub
parent 66a4205c57
commit f643fc3c97
2 changed files with 39 additions and 16 deletions

View File

@@ -147,6 +147,11 @@ describe("buildMinimaxSpeechProvider", () => {
expect(provider.isConfigured({ providerConfig: {}, timeoutMs: 30000 })).toBe(true);
});
it("returns false when MINIMAX_API_KEY env var is blank", () => {
process.env.MINIMAX_API_KEY = " ";
expect(provider.isConfigured({ providerConfig: {}, timeoutMs: 30000 })).toBe(false);
});
it("returns true when a MiniMax Token Plan env var is set", () => {
expect(tokenPlanEnvConfigured).toBe(true);
});
@@ -606,6 +611,22 @@ describe("buildMinimaxSpeechProvider", () => {
timeoutMs: 30000,
}),
).rejects.toThrow("MiniMax TTS auth missing");
expect(globalThis.fetch).not.toHaveBeenCalled();
});
it("does not send a request for a blank environment API key", async () => {
process.env.MINIMAX_API_KEY = " ";
await expect(
provider.synthesize({
text: "Test",
cfg: {} as never,
providerConfig: {},
target: "audio-file",
timeoutMs: 30000,
}),
).rejects.toThrow("MiniMax TTS auth missing");
expect(globalThis.fetch).not.toHaveBeenCalled();
});
it("throws on API error with response body", async () => {

View File

@@ -15,6 +15,7 @@ import type {
import {
asObject,
parseSpeechDirectiveNumberOverride,
resolveSpeechProviderApiKey,
trimToUndefined,
} from "openclaw/plugin-sdk/speech-core";
import { asFiniteNumberInRange } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -59,13 +60,9 @@ function resolveConfiguredPortalTtsBaseUrl(cfg: OpenClawConfig | undefined): str
}
function resolveMinimaxTokenPlanEnvKey(): string | undefined {
for (const envVar of MINIMAX_TOKEN_PLAN_ENV_VARS) {
const value = trimToUndefined(process.env[envVar]);
if (value) {
return value;
}
}
return undefined;
return resolveSpeechProviderApiKey(
...MINIMAX_TOKEN_PLAN_ENV_VARS.map((envVar) => process.env[envVar]),
);
}
async function resolveMinimaxPortalProfileToken(
@@ -81,11 +78,18 @@ async function resolveMinimaxTtsApiKey(params: {
cfg: OpenClawConfig | undefined;
configApiKey?: string;
}): Promise<string | undefined> {
return (
params.configApiKey ??
(await resolveMinimaxPortalProfileToken(params.cfg)) ??
resolveMinimaxTokenPlanEnvKey() ??
trimToUndefined(process.env.MINIMAX_API_KEY)
return resolveSpeechProviderApiKey(
params.configApiKey,
await resolveMinimaxPortalProfileToken(params.cfg),
resolveMinimaxDirectTtsApiKey(),
);
}
function resolveMinimaxDirectTtsApiKey(configApiKey?: string): string | undefined {
return resolveSpeechProviderApiKey(
configApiKey,
resolveMinimaxTokenPlanEnvKey(),
process.env.MINIMAX_API_KEY,
);
}
@@ -279,10 +283,8 @@ export function buildMinimaxSpeechProvider(): SpeechProviderPlugin {
listVoices: async () => MINIMAX_TTS_VOICES.map((voice) => ({ id: voice, name: voice })),
isConfigured: ({ cfg, providerConfig }) =>
Boolean(
readMinimaxProviderConfig(providerConfig, cfg).apiKey ||
isProviderAuthProfileConfigured({ cfg, provider: MINIMAX_PORTAL_PROVIDER_ID }) ||
resolveMinimaxTokenPlanEnvKey() ||
process.env.MINIMAX_API_KEY,
resolveMinimaxDirectTtsApiKey(readMinimaxProviderConfig(providerConfig, cfg).apiKey) ||
isProviderAuthProfileConfigured({ cfg, provider: MINIMAX_PORTAL_PROVIDER_ID }),
),
synthesize: async (req) => {
const config = readMinimaxProviderConfig(req.providerConfig, req.cfg);