Skip to content

Add MiniMax summarizer provider - #218

Open
octo-patch wants to merge 4 commits into
VasiHemanth:mainfrom
octo-patch:octo/20260801-provider-add-recvqnd27boLQh
Open

Add MiniMax summarizer provider#218
octo-patch wants to merge 4 commits into
VasiHemanth:mainfrom
octo-patch:octo/20260801-provider-add-recvqnd27boLQh

Conversation

@octo-patch

Copy link
Copy Markdown

Reason: Make MiniMax directly configurable for trace summarization across supported regions and compatible protocols.

Changes:

  • Add a MiniMax HTTP summarizer with current model selection, regional routing, and model-specific thinking behavior.
  • Add persisted settings, connection testing, and onboarding controls for the new backend.
  • Cover every region and protocol endpoint combination, response parsing, registry exposure, and config coercion.

Checks:

  • git diff --check HEAD^
  • PYTHONPATH=backend python3 backend/test_minimax_summarizer.py
  • frontend/node_modules/.bin/eslint --config frontend/eslint.config.mjs frontend/src/app/settings/page.tsx frontend/src/components/summarizer/BackendPicker.tsx frontend/src/components/summarizer/OnboardingModal.tsx frontend/src/lib/agents.ts frontend/src/lib/summarizer.ts --rule 'react-hooks/set-state-in-effect: off'
  • npm --prefix frontend run build

The repository-wide npm --prefix frontend run lint check still reports existing lint failures outside this change.

VasiHemanth and others added 2 commits August 1, 2026 15:42
MiniMax speaks the OpenAI chat-completions API, so it already works through
the openai_compat backend — the only friction was knowing the base URL and
model id. Add preset buttons that fill both in (MiniMax global, MiniMax China,
local llama.cpp) instead of a per-vendor adapter.

Verified the endpoint through the existing adapter: an unauthenticated POST to
https://api.minimax.io/v1/chat/completions returns MiniMax's 401 body, which
errors.classify() already buckets as `auth` with the right hint.

Adding a provider is one entry in ENDPOINT_PRESETS, not a new module, a
hardcoded model allowlist, and a test-connection route.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@VasiHemanth

Copy link
Copy Markdown
Owner

I've reverted the dedicated adapter on this branch and replaced it with endpoint presets on the existing openai_compat backend. Net diff vs main is now 3 files, +54/-4, instead of 10 files and +668/-19.

Why

MiniMax speaks the OpenAI chat-completions API, so it already worked through openai_compat before this PR. The only friction was knowing the base URL and the model id, which a preset solves.

Three things the dedicated adapter got wrong that the existing one already handles:

  1. <think> blocks leak. On the OpenAI route with reasoning_split unset (the default), M3 inlines its reasoning into content wrapped in <think> tags. openai_compat strips those (_THINK_RE, backend/summarizers/openai_compat.py:53). _extract_openai_text in minimax.py did not, so the full chain-of-thought would reach parse_narrative, which expects JSON.

  2. Hardcoded model allowlist. SUPPORTED_MODELS = ("MiniMax-M3", "MiniMax-M2.7") plus save_config silently rewriting model back to DEFAULT_MODEL when it isn't in that tuple (asserted on purpose in test_minimax_config_is_coerced_and_persisted). The next MiniMax model would be unusable until we cut a release. The free-text model field has no such gate.

  3. Unrelated cross-backend changes. ModelDropdown's loading ? to loading || (!options && !error) ? changes rendering for ollama and codex too, and moving get_summarizer(...) inside the try in make_summary turns constructor-raised SummarizerError (such as openai_compat's SSRF scheme guard) into a soft gen_error for every backend. Neither is mentioned in the description.

Separately, every test in test_minimax_summarizer.py mocked _post, so the endpoint-matrix test asserted that the code builds the URL the code intends to build. Nothing validated the {"type": "adaptive"} thinking shape against a real response.

What's on the branch now

  • ENDPOINT_PRESETS in frontend/src/lib/summarizer.ts: MiniMax, MiniMax (China), local llama.cpp. Each entry is an endpoint plus a starting model id.
  • Preset buttons above the Endpoint field in the existing OpenAICompatForm. Clicking one fills endpoint and model; the API key and sampling knobs stay the user's.

Adding the next provider is one array entry.

Verified

  • Unauthenticated POST through OpenAICompatSummarizer to https://api.minimax.io/v1/chat/completions returns MiniMax's 401 body, and errors.classify() buckets it as auth with the right hint.
  • <think> inlining confirmed against MiniMax's OpenAI SDK docs.
  • npx tsc --noEmit clean, UPDATE.json parses.

Needs a human check before merge

I don't have a MiniMax API key, so the authenticated end-to-end run hasn't happened. Please verify:

  1. Settings, Summaries, pick "OpenAI-compatible server", click the MiniMax preset.
  2. Paste your key, hit Test connection. Expect a short reply, not an error card.
  3. Open a session and generate a summary. Confirm the narrative renders and no <think> text appears in it.

If step 3 shows reasoning text, that's a _THINK_RE gap worth fixing in openai_compat for all reasoning models, not a reason to bring the adapter back.

A preset with an empty model left the previous id in place, so clicking
MiniMax and then the local llama.cpp preset would POST model "MiniMax-M3"
to localhost:8080. Reassign unconditionally; null falls through to
openai_compat's `self._model or "default"`, which is what a local server
that serves whatever is loaded expects.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@VasiHemanth

Copy link
Copy Markdown
Owner

Follow-up on the local-server case.

The openai_compat adapter itself is untouched by this PR, so llama.cpp works exactly as before: the endpoint field still defaults to http://localhost:8080/v1, the non-OpenAI sampling extras (top_k, min_p, repetition_penalty) still go out, and the 400 retry still drops them for strict servers.

One bug in the preset buttons though, now fixed in 81595e7: a preset with an empty model id left the previous one in place, so clicking MiniMax and then the local preset would POST model: "MiniMax-M3" to localhost:8080. The click now reassigns unconditionally, and a null model falls through to self._model or "default" in openai_compat.py:132, which is what a server that serves whatever is loaded expects.

Add to the verification pass: after testing MiniMax, click the local preset and confirm the model field clears rather than keeping the MiniMax id.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants