diff --git a/docs/superpowers/plans/2026-07-04-minimax-openai-response-sanitize.md b/docs/superpowers/plans/2026-07-04-minimax-openai-response-sanitize.md
new file mode 100644
index 000000000000..f400179ed722
--- /dev/null
+++ b/docs/superpowers/plans/2026-07-04-minimax-openai-response-sanitize.md
@@ -0,0 +1,87 @@
+# MiniMax OpenAI Response Sanitization Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Fix MiniMax OpenAI-format text responses so provider-specific fields do not leak into strict OpenAI clients.
+
+**Architecture:** Keep the fix local to the MiniMax adaptor. MiniMax already delegates text response handling to the OpenAI adaptor; the implementation will force the existing OpenAI DTO formatting path before delegation.
+
+**Tech Stack:** Go 1.22+, Gin test context, `github.com/stretchr/testify/require` and `assert`.
+
+---
+
+## Task 1: Non-Streaming Regression Test
+
+**Files:**
+- Modify: `relay/channel/minimax/adaptor_test.go`
+
+- [ ] **Step 1: Write the failing test**
+
+Add a test that sends a MiniMax-style non-streaming response with extra top-level and message fields through `Adaptor.DoResponse`. Assert the recorded response keeps OpenAI fields and omits MiniMax-only fields.
+
+- [ ] **Step 2: Run test to verify it fails**
+
+Run: `go test ./relay/channel/minimax -run TestDoResponseForOpenAITextStripsMiniMaxFields -count=1`
+
+Expected before implementation: FAIL because `input_sensitive`, `base_resp`, `name`, or `audio_content` appears in the response body.
+
+## Task 2: Streaming Regression Test
+
+**Files:**
+- Modify: `relay/channel/minimax/adaptor_test.go`
+
+- [ ] **Step 1: Write the failing test**
+
+Add a streaming test that sends SSE chunks containing MiniMax-only `delta.name`, `delta.audio_content`, and a final chunk containing `choices[].message`. Assert the downstream SSE omits those fields and still emits `[DONE]`.
+
+- [ ] **Step 2: Run test to verify it fails**
+
+Run: `go test ./relay/channel/minimax -run TestDoResponseForOpenAIStreamStripsMiniMaxFieldsAndMessage -count=1`
+
+Expected before implementation: FAIL because raw SSE chunks are forwarded with `name`, `audio_content`, or `message`.
+
+## Task 3: Minimal Implementation
+
+**Files:**
+- Modify: `relay/channel/minimax/adaptor.go`
+- Modify: `relay/channel/openai/relay-openai.go`
+
+- [ ] **Step 1: Force formatting for MiniMax OpenAI text responses**
+
+In `Adaptor.DoResponse`, before delegating to `openai.Adaptor`, set `info.ChannelSetting.ForceFormat = true` when:
+
+- `info.RelayFormat` is `types.RelayFormatOpenAI`
+- `info.RelayMode` is `constant.RelayModeChatCompletions`
+
+- [ ] **Step 2: Run targeted tests**
+
+In `OpenaiHandler`, when `forceFormat` is true, clear `simpleResponse.Choices[i].Message.Name` before marshalling the response.
+
+- [ ] **Step 3: Run targeted tests**
+
+Run: `go test ./relay/channel/minimax -count=1`
+
+Expected after implementation: PASS.
+
+## Task 4: Related Verification
+
+**Files:**
+- No production edits expected.
+
+- [ ] **Step 1: Run delegated OpenAI handler tests**
+
+Run: `go test ./relay/channel/openai -count=1`
+
+Expected: PASS.
+
+- [ ] **Step 2: Run touched relay package tests**
+
+Run: `go test ./relay/channel/minimax ./relay/channel/openai -count=1`
+
+Expected: PASS.
+
+- [ ] **Step 3: Inspect diff**
+
+Run: `git diff -- relay/channel/minimax/adaptor.go relay/channel/minimax/adaptor_test.go docs/superpowers/specs/2026-07-04-minimax-openai-response-sanitize-design.md docs/superpowers/plans/2026-07-04-minimax-openai-response-sanitize.md`
+
+Expected: Only the planned MiniMax adaptor, tests, and docs changed.
diff --git a/docs/superpowers/reports/minimax-openai-response-sanitize-review.html b/docs/superpowers/reports/minimax-openai-response-sanitize-review.html
new file mode 100644
index 000000000000..05737337c8fb
--- /dev/null
+++ b/docs/superpowers/reports/minimax-openai-response-sanitize-review.html
@@ -0,0 +1,477 @@
+
+
+
if forceFormat {
+ for i := range simpleResponse.Choices {
+ simpleResponse.Choices[i].Message.Name = nil
+ }
+ responseBody, err = common.Marshal(simpleResponse)
+}
+
+
+
+
+
+
diff --git a/docs/superpowers/specs/2026-07-04-minimax-openai-response-sanitize-design.md b/docs/superpowers/specs/2026-07-04-minimax-openai-response-sanitize-design.md
new file mode 100644
index 000000000000..1b93e31a824a
--- /dev/null
+++ b/docs/superpowers/specs/2026-07-04-minimax-openai-response-sanitize-design.md
@@ -0,0 +1,76 @@
+# MiniMax OpenAI Response Sanitization Design
+
+## Context
+
+On 2026-07-04, `main` was synchronized from upstream `QuantumNous/new-api` to fork `zhukangfeng/new-api` at commit `722d0366b727b82fced878af902e48363626b2fb`.
+
+I reviewed open issues and excluded items that already had an open PR, assignee, insufficient reproduction, or a larger feature scope. The selected issues are:
+
+- [#5833](https://github.com/QuantumNous/new-api/issues/5833): MiniMax streaming responses can emit a final chunk containing a non-streaming `message` object.
+- [#5834](https://github.com/QuantumNous/new-api/issues/5834): MiniMax OpenAI-compatible responses leak non-OpenAI fields such as `name`, `audio_content`, `input_sensitive`, `service_tier`, and `base_resp`.
+
+These issues are urgent because strict OpenAI-compatible clients can reject the response schema or duplicate assistant output. They are unassigned and have no obvious open PR in the current open PR list.
+
+## Root Cause
+
+MiniMax text chat uses the MiniMax adaptor for request URL/header selection, but response handling delegates to the generic OpenAI adaptor.
+
+The generic OpenAI handler has two behaviors:
+
+- Without `force_format`, it forwards upstream JSON/SSE chunks nearly as received.
+- With `force_format`, it unmarshals into project OpenAI DTOs and marshals back, which keeps only supported OpenAI response fields.
+
+MiniMax upstream chat responses can include provider-specific fields. Because the MiniMax adaptor does not force formatting for text responses, those provider-specific fields pass through to OpenAI clients.
+
+## Design
+
+For MiniMax text responses in OpenAI relay format, force OpenAI DTO formatting before delegating to the OpenAI response handler.
+
+This keeps the change local to MiniMax and avoids changing behavior for generic OpenAI-compatible channels that intentionally rely on raw pass-through behavior.
+
+The response path will be:
+
+1. MiniMax text request reaches `relay/channel/minimax.Adaptor.DoResponse`.
+2. If `RelayFormat` is OpenAI and the relay mode is text chat, set `info.ChannelSetting.ForceFormat = true`.
+3. Delegate to `openai.Adaptor.DoResponse` as today.
+4. Existing OpenAI handler strips unsupported fields by unmarshalling into `dto.OpenAITextResponse` or `dto.ChatCompletionsStreamResponse`.
+5. In forced-format non-streaming responses, clear `choices[].message.name` before marshalling because the shared request/response `dto.Message` type accepts request-side `name`, but the MiniMax value is provider metadata rather than OpenAI response content.
+
+## Behavioral Contract
+
+Non-streaming MiniMax text responses returned through `/v1/chat/completions` must:
+
+- Preserve standard OpenAI fields: `id`, `object`, `created`, `model`, `choices`, `usage`.
+- Preserve `choices[].message.role`, `choices[].message.content`, and supported reasoning/tool fields.
+- Omit MiniMax-only top-level fields: `input_sensitive`, `output_sensitive`, `input_sensitive_type`, `output_sensitive_type`, `output_sensitive_int`, `service_tier`, `base_resp`.
+- Omit MiniMax-only message fields: `name`, `audio_content`.
+
+Streaming MiniMax text responses returned through `/v1/chat/completions` must:
+
+- Preserve standard OpenAI SSE chunks.
+- Preserve `delta.role`, `delta.content`, `delta.reasoning_content`, `delta.reasoning`, and `delta.tool_calls`.
+- Omit MiniMax-only delta fields such as `name` and `audio_content`.
+- Omit any stream-only `choices[].message` object from chunks; stream chunks should use `delta`.
+
+## Files
+
+- Modify `relay/channel/minimax/adaptor.go` to force response formatting for OpenAI-format text responses.
+- Modify `relay/channel/openai/relay-openai.go` to omit response message `name` in the forced-format path.
+- Add tests in `relay/channel/minimax/adaptor_test.go` covering non-streaming and streaming response sanitization.
+
+## Testing
+
+Use test-driven development:
+
+1. Add a failing non-streaming test with MiniMax-only top-level and message fields.
+2. Add a failing streaming test with MiniMax-only delta fields and a final `message` field.
+3. Implement the minimal MiniMax adaptor change.
+4. Run targeted Go tests for `relay/channel/minimax`.
+5. Run related OpenAI channel tests to ensure the delegated handler behavior still passes.
+6. Run a broader Go test command for touched packages.
+
+## Risks
+
+The change intentionally affects only MiniMax text chat responses in OpenAI relay format. MiniMax image, TTS, and Claude-format response paths are left unchanged.
+
+If an operator depended on MiniMax-specific fields leaking through the OpenAI endpoint, those fields will no longer be present. This is acceptable because the endpoint contract is OpenAI-compatible output.
diff --git a/relay/channel/minimax/adaptor_test.go b/relay/channel/minimax/adaptor_test.go
index 46d57c11ff72..4f98adf9c52f 100644
--- a/relay/channel/minimax/adaptor_test.go
+++ b/relay/channel/minimax/adaptor_test.go
@@ -13,6 +13,8 @@ import (
relayconstant "github.com/QuantumNous/new-api/relay/constant"
"github.com/gin-gonic/gin"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetRequestURLForImageGeneration(t *testing.T) {
@@ -36,6 +38,23 @@ func TestGetRequestURLForImageGeneration(t *testing.T) {
}
}
+func TestGetRequestURLForChatCompletionsUsesOpenAICompatibleEndpoint(t *testing.T) {
+ t.Parallel()
+
+ info := &relaycommon.RelayInfo{
+ RelayMode: relayconstant.RelayModeChatCompletions,
+ ChannelMeta: &relaycommon.ChannelMeta{
+ ChannelBaseUrl: "https://api.minimax.chat",
+ },
+ }
+
+ got, err := GetRequestURL(info)
+ require.NoError(t, err, "GetRequestURL returned error")
+
+ want := "https://api.minimax.chat/v1/chat/completions"
+ assert.Equal(t, want, got)
+}
+
func TestConvertImageRequest(t *testing.T) {
t.Parallel()
diff --git a/relay/channel/minimax/relay-minimax.go b/relay/channel/minimax/relay-minimax.go
index a1a05150c00f..3441f5d74691 100644
--- a/relay/channel/minimax/relay-minimax.go
+++ b/relay/channel/minimax/relay-minimax.go
@@ -20,7 +20,7 @@ func GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
default:
switch info.RelayMode {
case constant.RelayModeChatCompletions:
- return fmt.Sprintf("%s/v1/text/chatcompletion_v2", baseUrl), nil
+ return fmt.Sprintf("%s/v1/chat/completions", baseUrl), nil
case constant.RelayModeImagesGenerations:
return fmt.Sprintf("%s/v1/image_generation", baseUrl), nil
case constant.RelayModeAudioSpeech: