From 4c734afe6d8948282b88ccd21c9cbb8dfd2f2ea3 Mon Sep 17 00:00:00 2001 From: oxoxDev <164490987+oxoxDev@users.noreply.github.com> Date: Mon, 8 Jun 2026 18:26:49 +0530 Subject: [PATCH] fix(inference): point MiniMax at its OpenAI-compatible /v1 endpoint (#3401) (#3402) --- .../settings/panels/__tests__/AIPanel.test.tsx | 9 ++++++--- .../__tests__/builtinCloudProviders.test.ts | 2 +- .../settings/panels/builtinCloudProviders.ts | 8 ++++++-- src/openhuman/config/schema/cloud_providers.rs | 16 ++++++++++++---- tests/config_auth_app_state_connectivity_e2e.rs | 6 ++++-- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/app/src/components/settings/panels/__tests__/AIPanel.test.tsx b/app/src/components/settings/panels/__tests__/AIPanel.test.tsx index ebba301f7..484fd48c8 100644 --- a/app/src/components/settings/panels/__tests__/AIPanel.test.tsx +++ b/app/src/components/settings/panels/__tests__/AIPanel.test.tsx @@ -427,7 +427,7 @@ describe('AIPanel', () => { ); }); - it('connects MiniMax with anthropic auth style', async () => { + it('connects MiniMax via its OpenAI-compatible /v1 endpoint with bearer auth', async () => { vi.mocked(loadAISettings).mockResolvedValue({ ...baseSettings, cloudProviders: [] }); renderWithProviders(); @@ -445,13 +445,16 @@ describe('AIPanel', () => { await waitFor(() => expect(vi.mocked(saveAISettings)).toHaveBeenCalled()); const [, nextSettings] = vi.mocked(saveAISettings).mock.calls[0]; + // MiniMax speaks OpenAI on `/v1` (chat/completions + models). The old + // `/anthropic` base + anthropic auth pointed at its Messages API, which + // OpenHuman doesn't speak — both paths 404'd (Sentry TAURI-RUST-8X3). expect(nextSettings.cloudProviders).toEqual( expect.arrayContaining([ expect.objectContaining({ slug: 'minimax', label: 'MiniMax', - endpoint: 'https://api.minimax.io/anthropic', - auth_style: 'anthropic', + endpoint: 'https://api.minimax.io/v1', + auth_style: 'bearer', }), ]) ); diff --git a/app/src/components/settings/panels/__tests__/builtinCloudProviders.test.ts b/app/src/components/settings/panels/__tests__/builtinCloudProviders.test.ts index 63d1c6f55..21f493063 100644 --- a/app/src/components/settings/panels/__tests__/builtinCloudProviders.test.ts +++ b/app/src/components/settings/panels/__tests__/builtinCloudProviders.test.ts @@ -15,7 +15,7 @@ describe('builtinCloudProviders', () => { it.each([ ['groq', 'https://api.groq.com/openai/v1', 'bearer'], ['deepseek', 'https://api.deepseek.com/v1', 'bearer'], - ['minimax', 'https://api.minimax.io/anthropic', 'anthropic'], + ['minimax', 'https://api.minimax.io/v1', 'bearer'], ['sumopod', 'https://ai.sumopod.com/v1', 'bearer'], ] as const)('maps %s to its endpoint and auth style', (slug, endpoint, authStyle) => { expect(defaultEndpointForBuiltinCloudProvider(slug)).toBe(endpoint); diff --git a/app/src/components/settings/panels/builtinCloudProviders.ts b/app/src/components/settings/panels/builtinCloudProviders.ts index 2ec0c32c0..9cf31e9e7 100644 --- a/app/src/components/settings/panels/builtinCloudProviders.ts +++ b/app/src/components/settings/panels/builtinCloudProviders.ts @@ -158,8 +158,12 @@ export const BUILTIN_CLOUD_PROVIDERS: BuiltinCloudProvider[] = [ { slug: 'minimax', label: 'MiniMax', - endpoint: 'https://api.minimax.io/anthropic', - authStyle: 'anthropic', + // OpenAI-compatible surface (`/v1/chat/completions`, `/v1/models`). The + // prior `/anthropic` base + anthropic auth hit MiniMax's Messages API, + // which OpenHuman doesn't speak — both chat and model-listing 404'd + // (Sentry TAURI-RUST-8X3). Keep in sync with the Rust catalog. + endpoint: 'https://api.minimax.io/v1', + authStyle: 'bearer', tone: TONE.rose, }, { diff --git a/src/openhuman/config/schema/cloud_providers.rs b/src/openhuman/config/schema/cloud_providers.rs index 0ec08375a..2bbef52bd 100644 --- a/src/openhuman/config/schema/cloud_providers.rs +++ b/src/openhuman/config/schema/cloud_providers.rs @@ -132,8 +132,16 @@ pub const BUILTIN_CLOUD_PROVIDERS: &[BuiltinCloudProvider] = &[ BuiltinCloudProvider { slug: "minimax", label: "MiniMax", - endpoint: "https://api.minimax.io/anthropic", - auth_style: AuthStyle::Anthropic, + // MiniMax exposes a full OpenAI-compatible surface at `/v1` + // (`/v1/chat/completions`, `/v1/models`). The previous `/anthropic` + // base + Anthropic auth pointed at MiniMax's Messages-protocol API, + // which OpenHuman does not speak — it only builds OpenAI-style + // `/chat/completions` and `/models` — so both chat and model-listing + // 404'd (`/anthropic/chat/completions`, `/anthropic/models`). The + // 404 on model-listing was Sentry TAURI-RUST-8X3. Use the `/v1` + // OpenAI surface with Bearer auth so both paths resolve. + endpoint: "https://api.minimax.io/v1", + auth_style: AuthStyle::Bearer, }, BuiltinCloudProvider { slug: "stepfun", @@ -507,8 +515,8 @@ mod tests { ( "minimax", "MiniMax", - "https://api.minimax.io/anthropic", - AuthStyle::Anthropic, + "https://api.minimax.io/v1", + AuthStyle::Bearer, ), ( "sumopod", diff --git a/tests/config_auth_app_state_connectivity_e2e.rs b/tests/config_auth_app_state_connectivity_e2e.rs index ee0def022..b992116c7 100644 --- a/tests/config_auth_app_state_connectivity_e2e.rs +++ b/tests/config_auth_app_state_connectivity_e2e.rs @@ -669,8 +669,10 @@ fn config_schema_helpers_cover_provider_voice_agent_and_channel_defaults() { migrate_legacy_fields(&mut minimax_legacy); assert_eq!(minimax_legacy.slug, "minimax"); assert_eq!(minimax_legacy.label, "MiniMax"); - assert_eq!(minimax_legacy.endpoint, "https://api.minimax.io/anthropic"); - assert_eq!(minimax_legacy.auth_style, AuthStyle::Anthropic); + // MiniMax uses its OpenAI-compatible /v1 surface + Bearer (TAURI-RUST-8X3); + // the legacy `type=minimax` migration fills from the corrected catalog. + assert_eq!(minimax_legacy.endpoint, "https://api.minimax.io/v1"); + assert_eq!(minimax_legacy.auth_style, AuthStyle::Bearer); assert_eq!(AuthStyle::OpenhumanJwt.as_str(), "openhuman_jwt"); assert_eq!(AuthStyle::Anthropic.as_str(), "anthropic"); assert_eq!(AuthStyle::None.as_str(), "none");