Skip to content

feat(minimax): add MiniMax provider support - #2306

Open
Bhavyashah20 wants to merge 7 commits into
567-labs:mainfrom
Bhavyashah20:feat/minimax-provider
Open

feat(minimax): add MiniMax provider support#2306
Bhavyashah20 wants to merge 7 commits into
567-labs:mainfrom
Bhavyashah20:feat/minimax-provider

Conversation

@Bhavyashah20

@Bhavyashah20 Bhavyashah20 commented May 14, 2026

Copy link
Copy Markdown

Summary

Adds first-class MiniMax support to instructor via from_minimax() and from_provider("minimax/...").

  • MINIMAX_TOOLS (default): uses the model's OpenAI-compatible tool-calling API for structured output
  • MINIMAX_JSON: injects the Pydantic schema into the system prompt — MiniMax does not support response_format, so tool calling is the preferred mode but JSON mode is available as a fallback
  • Think-tag stripping: MiniMax reasoning models prepend <think>…</think> blocks before their answer in JSON mode; these are stripped automatically before JSON parsing so callers never see them
  • No new SDK dependency — uses the standard openai package pointed at https://api.minimax.io/v1

Usage

import os, openai, instructor
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

# one-liner
client = instructor.from_provider("minimax/MiniMax-M2.7")

# or explicit
raw = openai.OpenAI(api_key=os.environ["MINIMAX_API_KEY"], base_url="https://api.minimax.io/v1")
client = instructor.from_minimax(raw)

user = client.chat.completions.create(
    model="MiniMax-M2.7",
    messages=[{"role": "user", "content": "Extract: Jason is 25 years old"}],
    response_model=User,
)
# User(name='Jason', age=25)

Files changed

File Change
instructor/v2/core/mode.py MINIMAX_TOOLS, MINIMAX_JSON added to Mode enum, tool_modes(), json_modes(), and DEPRECATED_TO_CORE
instructor/v2/core/providers.py Provider.MINIMAX added, wired in provider_from_mode() and get_provider()
instructor/v2/core/provider_specs.py PROVIDER_SPECS entry for MiniMax — supported/unsupported modes, legacy mode aliases, factory function reference
instructor/v2/providers/minimax/handlers.py MiniMaxToolsHandler (extends OpenAIToolsHandler) and MiniMaxMDJSONHandler (injects schema into system prompt, strips think-tags)
instructor/v2/providers/minimax/client.py from_minimax() factory using _from_openai_compat(), defaults to Mode.TOOLS
instructor/v2/providers/minimax/__init__.py Exports from_minimax, both handler classes
instructor/v2/auto_client.py _build_minimax() builder added to _PROVIDER_BUILDERS dict
instructor/providers/minimax/client.py Thin shim re-exporting from instructor.v2.providers.minimax.client
instructor/__init__.py from_minimax added to _LAZY_IMPORTS and _add_optional_export
docs/integrations/minimax.md Full integration docs with sync/async/nested examples
tests/llm/test_minimax/ Integration tests (auto-skipped without MINIMAX_API_KEY)
mkdocs.yml Navigation entry under Integrations
CHANGELOG.md Unreleased entry

Closes #2260

Adds first-class support for MiniMax via from_minimax() and
from_provider("minimax/...").

- New provider at instructor/providers/minimax/ with client.py and
  utils.py (handles_minimax_tools, handle_minimax_json, reask handlers)
- MINIMAX_TOOLS mode: uses OpenAI-compatible tool calling
- MINIMAX_JSON mode: injects schema via system prompt (MiniMax does not
  support response_format); strips <think>...</think> blocks emitted by
  reasoning models before JSON parsing
- Provider enum + URL detection in utils/providers.py
- Auto-client routing in auto_client.py (reads MINIMAX_API_KEY)
- Docs at docs/integrations/minimax.md
- Integration tests in tests/llm/test_minimax/ (skipped without key)

Closes 567-labs#2260
Resolves conflicts from the v2 migration refactor (60cc815) by properly
integrating MiniMax into the v2 provider system instead of keeping
the old pre-v2 implementations.

Changes:
- Restore mode.py, utils/providers.py, auto_client.py, processing/*.py
  to v2 shim stubs (pointing to instructor.v2.* implementations)
- Add MINIMAX_TOOLS / MINIMAX_JSON to instructor/v2/core/mode.py
- Add Provider.MINIMAX + URL detection to instructor/v2/core/providers.py
- Add Provider.MINIMAX spec to instructor/v2/core/provider_specs.py
- Create instructor/v2/providers/minimax/ with client.py, handlers.py,
  __init__.py following the v2 registry pattern
- Add _build_minimax to instructor/v2/auto_client.py
- Add from_minimax lazy import to instructor/__init__.py
- Convert instructor/providers/minimax/ to v2 compat shims
@Bhavyashah20
Bhavyashah20 force-pushed the feat/minimax-provider branch from fdb2008 to c3bde51 Compare May 18, 2026 11:30
@Bhavyashah20

Copy link
Copy Markdown
Author

Just wanted to flag the architecture note for reviewers: this follows the v2 provider pattern introduced in the recent refactor. MiniMax is registered via PROVIDER_SPECS in instructor/v2/core/provider_specs.py, the handlers live in instructor/v2/providers/minimax/, and instructor/providers/minimax/client.py is a thin shim for backward compatibility.

The one non-obvious design choice: MINIMAX_JSON mode injects the Pydantic schema directly into the system prompt rather than using response_format, because MiniMax's API doesn't support response_format on all models. Think-tag stripping happens in the handler before JSON parsing so callers never see raw <think>…</think> output.

Happy to adjust anything if this doesn't align with where the v2 architecture is heading.

@Bhavyashah20

Copy link
Copy Markdown
Author

Hi, just following up on this PR — it's been open for a few weeks and wanted to check if there's anything needed from my side or if there are any concerns with the changes. Happy to revise if anything looks off. Thanks!

jxnl added a commit that referenced this pull request Aug 3, 2026
## Summary

- accumulate declared, nested, and unknown numeric OpenAI/Anthropic
usage fields across retries while preserving non-numeric metadata
- add corrective feedback when a Responses API retry receives no tool
call
- preserve raw iterable type hints through sync and async v2
parallel-tool wrappers
- strengthen API-key-free coverage for current and future SDK usage
counters

## Consolidated and superseded items

- closes #2493
- consolidates contributor work from #2498, #2500, and #2501 with
original commit authorship preserved
- supersedes #2497 because it drops unknown `model_extra` counters
- supersedes #2499 because its hand-maintained provider field lists
would drift as SDKs evolve

## Validation

- focused changed-surface suite: `110 passed`
- broad offline v2/coverage suite: `2368 passed, 91 skipped, 73
deselected`
- Ruff check and format check: passed
- scoped `ty check`: passed
- `uv lock --check`: passed
- pre-commit hooks and `git diff --check`: passed

The 73 deselected tests require live provider credentials. An unfiltered
local run confirmed its 22 failures were provider network connections in
the restricted environment; GitHub provider jobs remain the
authoritative validation for those paths.

## Intentionally skipped

- provider additions or expansions: #2436, #2435, #2423, #2409, #2384,
#2322, #2306, #2298, #2283, #2168, #2086; issues #2408, #2383, #2365,
#2260, #2084, #2076
- broad architecture, product, security, or streaming decisions: #2394,
#2392, #2357, #2356, #2355, #2351, #2321, #2307, #2287, #2263; issues
#2479, #2403, #2393, #2391, #2316, #2272, #2056
- dependency batch: #2433
- nontrivial examples and editorial/resource additions: #2468, #2405,
#2401, #2354, #2346, #2311, #2305; issue #2404

These remain open because they need dedicated product, architecture,
provider, security, dependency, or editorial review and are not required
for the `1.15.5` patch release.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes retry usage totals and reask message content on failure paths;
scope is limited and heavily covered by tests, with no auth or
data-store changes.
> 
> **Overview**
> Bundles three v2 retry and wrapper fixes for a patch release.
> 
> **Retry usage accounting** replaces hand-maintained token field sums
with generic `_accumulate_models` on Pydantic usage objects. Numeric
fields (including nested models and `model_extra` counters) add across
retries; booleans and other non-numeric metadata are not treated as
billable. OpenAI and Anthropic paths share this logic.
> 
> **OpenAI Responses reask** appends a user correction when
`RESPONSES_TOOLS` validation fails but the output has no tool calls
(e.g. reasoning-only), so retries include feedback instead of repeating
the same request.
> 
> **Parallel tools** in `patch_v2` skips `prepare_response_model` and
does not replace `response_model` with the handler’s prepared wrapper
for parallel modes, keeping raw `Iterable[...]` hints so schemas and
parsed results include every member type.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
bbddca1. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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.

feat: add MiniMax provider support

2 participants