feat(bedrock): add MiniMax provider support for AWS Bedrock (#4609)
This commit is contained in:
@@ -220,6 +220,25 @@ class TestBuildInferenceConfig:
|
||||
cfg = llm._build_inference_config()
|
||||
assert cfg["maxTokens"] == 2000
|
||||
|
||||
def test_minimax_omits_top_p_when_explicitly_set(self, mock_boto3):
|
||||
# MiniMax M2.x (reasoning model) rejects both temperature and topP simultaneously.
|
||||
# Even when the user explicitly configures top_p, it must be omitted.
|
||||
llm = _make_llm(
|
||||
"minimax.minimax-m2.5",
|
||||
mock_boto3,
|
||||
temperature=0.1,
|
||||
top_p=0.9,
|
||||
)
|
||||
cfg = llm._build_inference_config()
|
||||
assert "temperature" in cfg
|
||||
assert "topP" not in cfg, "topP must be absent for MiniMax reasoning models"
|
||||
|
||||
def test_minimax_only_temperature_by_default(self, mock_boto3):
|
||||
llm = _make_llm("minimax.minimax-m2.5", mock_boto3, temperature=0.1)
|
||||
cfg = llm._build_inference_config()
|
||||
assert cfg["temperature"] == 0.1
|
||||
assert "topP" not in cfg
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# generate_response — Converse API call assertions
|
||||
@@ -328,3 +347,80 @@ class TestGenerateResponseConverse:
|
||||
|
||||
_, kwargs = mock_boto3.converse.call_args
|
||||
assert "topP" not in kwargs["inferenceConfig"]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# MiniMax provider
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestMiniMaxProvider:
|
||||
"""Tests for MiniMax models via Bedrock Converse API."""
|
||||
|
||||
def test_extract_provider(self):
|
||||
assert extract_provider("minimax.minimax-m2.5") == "minimax"
|
||||
assert extract_provider("minimax.minimax-m2") == "minimax"
|
||||
|
||||
def test_generate_response_text_only(self, mock_boto3):
|
||||
"""Standard response: single text block."""
|
||||
mock_boto3.converse.return_value = _converse_response("Hello!")
|
||||
llm = _make_llm("minimax.minimax-m2.5", mock_boto3)
|
||||
|
||||
result = llm.generate_response([{"role": "user", "content": "say hi"}])
|
||||
|
||||
assert result == "Hello!"
|
||||
_, kwargs = mock_boto3.converse.call_args
|
||||
assert kwargs["modelId"] == "minimax.minimax-m2.5"
|
||||
assert kwargs["messages"][0]["role"] == "user"
|
||||
assert kwargs["messages"][0]["content"][0]["text"] == "say hi"
|
||||
|
||||
def test_generate_response_reasoning_model(self, mock_boto3):
|
||||
"""MiniMax M2.5 is a reasoning model: reasoningContent block comes before text."""
|
||||
reasoning_response = {
|
||||
"output": {
|
||||
"message": {
|
||||
"content": [
|
||||
{"reasoningContent": {"reasoningText": {"text": "Let me think..."}}},
|
||||
{"text": "Hello!"},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
mock_boto3.converse.return_value = reasoning_response
|
||||
llm = _make_llm("minimax.minimax-m2.5", mock_boto3)
|
||||
|
||||
result = llm.generate_response([{"role": "user", "content": "say hi"}])
|
||||
|
||||
# Must skip reasoningContent and return the actual text block
|
||||
assert result == "Hello!"
|
||||
|
||||
def test_inference_config(self, mock_boto3):
|
||||
"""inferenceConfig should include maxTokens and temperature; no topP."""
|
||||
mock_boto3.converse.return_value = _converse_response()
|
||||
llm = _make_llm("minimax.minimax-m2.5", mock_boto3, temperature=0.2, max_tokens=512)
|
||||
|
||||
llm.generate_response([{"role": "user", "content": "hi"}])
|
||||
|
||||
_, kwargs = mock_boto3.converse.call_args
|
||||
assert kwargs["inferenceConfig"]["maxTokens"] == 512
|
||||
assert kwargs["inferenceConfig"]["temperature"] == 0.2
|
||||
assert "topP" not in kwargs["inferenceConfig"]
|
||||
|
||||
def test_system_prompt_passed_correctly(self, mock_boto3):
|
||||
"""System messages must be sent via top-level `system` param, not as a message role."""
|
||||
mock_boto3.converse.return_value = _converse_response('{"facts": ["test"]}')
|
||||
llm = _make_llm("minimax.minimax-m2.5", mock_boto3)
|
||||
|
||||
llm.generate_response([
|
||||
{"role": "system", "content": "Return JSON only."},
|
||||
{"role": "user", "content": "Extract facts from: test"},
|
||||
])
|
||||
|
||||
_, kwargs = mock_boto3.converse.call_args
|
||||
# system prompt must be in top-level "system" key
|
||||
assert "system" in kwargs
|
||||
assert kwargs["system"][0]["text"] == "Return JSON only."
|
||||
# messages list must NOT contain a system role entry
|
||||
for msg in kwargs["messages"]:
|
||||
assert msg["role"] != "system"
|
||||
# user message must be present
|
||||
assert kwargs["messages"][0]["role"] == "user"
|
||||
|
||||
Reference in New Issue
Block a user