diff --git a/tests/integration/proxy_config.yaml b/tests/integration/proxy_config.yaml index 927f8c74474..9e4a90fc608 100644 --- a/tests/integration/proxy_config.yaml +++ b/tests/integration/proxy_config.yaml @@ -274,6 +274,54 @@ model_list: vertex_project: synthetic-vertex-project vertex_location: global vertex_credentials: '{"type": "external_account", "audience": "synthetic-vertex-audience", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "token_url": "http://127.0.0.1:8190/_oauth/token", "credential_source": {"url": "http://127.0.0.1:8190/health"}}' + - model_name: bedrock_mantle/anthropic.claude-haiku-4-5 + litellm_params: + model: bedrock_mantle/anthropic.claude-haiku-4-5 + api_base: http://127.0.0.1:8191 + api_key: synthetic-bedrock-mantle-key + aws_region_name: us-east-1 + - model_name: bedrock_mantle/anthropic.claude-sonnet-5 + litellm_params: + model: bedrock_mantle/anthropic.claude-sonnet-5 + api_base: http://127.0.0.1:8191 + api_key: synthetic-bedrock-mantle-key + aws_region_name: us-east-1 + - model_name: bedrock_mantle/anthropic.claude-opus-5-5 + litellm_params: + model: bedrock_mantle/anthropic.claude-opus-5-5 + api_base: http://127.0.0.1:8191 + api_key: synthetic-bedrock-mantle-key + aws_region_name: us-east-1 + - model_name: bedrock_mantle/openai.gpt-5.4 + litellm_params: + model: bedrock_mantle/openai.gpt-5.4 + api_base: http://127.0.0.1:8191 + api_key: synthetic-bedrock-mantle-key + aws_region_name: us-east-1 + - model_name: bedrock_mantle/openai.gpt-5.6-sol + litellm_params: + model: bedrock_mantle/openai.gpt-5.6-sol + api_base: http://127.0.0.1:8191 + api_key: synthetic-bedrock-mantle-key + aws_region_name: us-east-1 + - model_name: bedrock_mantle/openai.gpt-5.6-luna + litellm_params: + model: bedrock_mantle/openai.gpt-5.6-luna + api_base: http://127.0.0.1:8191 + api_key: synthetic-bedrock-mantle-key + aws_region_name: us-east-1 + - model_name: bedrock_mantle/openai.gpt-6-luna + litellm_params: + model: bedrock_mantle/openai.gpt-6-luna + api_base: http://127.0.0.1:8191 + api_key: synthetic-bedrock-mantle-key + aws_region_name: us-east-1 + - model_name: bedrock_mantle/openai.gpt-6.1-sol + litellm_params: + model: bedrock_mantle/openai.gpt-6.1-sol + api_base: http://127.0.0.1:8191 + api_key: synthetic-bedrock-mantle-key + aws_region_name: us-east-1 general_settings: master_key: os.environ/LITELLM_MASTER_KEY database_url: os.environ/DATABASE_URL diff --git a/tests/integration/translation/chat_completions/bases/bedrock_mantle.py b/tests/integration/translation/chat_completions/bases/bedrock_mantle.py new file mode 100644 index 00000000000..458f0834a86 --- /dev/null +++ b/tests/integration/translation/chat_completions/bases/bedrock_mantle.py @@ -0,0 +1,728 @@ +from typing import Final +from unittest.mock import ANY + +from integration.translation.case import TranslationTestCase + + +CLAUDE_HAIKU_4_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-haiku-4-5", + "max_tokens": 64, + "messages": [ + {"role": "system", "content": "You are a terse assistant."}, + {"role": "user", "content": "Say hello."}, + ], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": [{"type": "text", "text": "Say hello."}]}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "anthropic_version": "bedrock-2023-05-31", + "model": "anthropic.claude-haiku-4-5", + }, + mock_provider_response={ + "model": "claude-haiku-4-5-20251001", + "id": "msg_bdrk_vmd4jw2bdh7lsarmxtb244m4pw3umtkcnlhschksadqqcpqfcmiq", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 17, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 5, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "id": ANY, + "created": ANY, + "model": "bedrock_mantle/anthropic.claude-haiku-4-5", + "object": "chat.completion", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "Hello.", + "role": "assistant", + "provider_specific_fields": {"citations": None, "thinking_blocks": None}, + }, + } + ], + "usage": { + "completion_tokens": 5, + "prompt_tokens": 17, + "total_tokens": 22, + "completion_tokens_details": {"reasoning_tokens": 0, "text_tokens": 5}, + "prompt_tokens_details": { + "cached_tokens": 0, + "text_tokens": 17, + "cache_write_tokens": 0, + "cache_creation_tokens": 0, + "cache_creation_token_details": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + }, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "service_tier": "standard", + }, + }, +) + + +CLAUDE_SONNET_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-sonnet-5", + "max_tokens": 64, + "messages": [ + {"role": "system", "content": "You are a terse assistant."}, + {"role": "user", "content": "Say hello."}, + ], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": [{"type": "text", "text": "Say hello."}]}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "anthropic_version": "bedrock-2023-05-31", + "model": "anthropic.claude-sonnet-5", + }, + mock_provider_response={ + "model": "claude-sonnet-5", + "id": "msg_bdrk_fxpfvo6z6ua32kp776ux7hv2ultohujjrfemqzl34vfdfaihltma", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 21, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"thinking_tokens": 0}, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "id": ANY, + "created": ANY, + "model": "bedrock_mantle/anthropic.claude-sonnet-5", + "object": "chat.completion", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "Hello.", + "role": "assistant", + "provider_specific_fields": {"citations": None, "thinking_blocks": None}, + }, + } + ], + "usage": { + "completion_tokens": 6, + "prompt_tokens": 21, + "total_tokens": 27, + "completion_tokens_details": {"reasoning_tokens": 0, "text_tokens": 6}, + "prompt_tokens_details": { + "cached_tokens": 0, + "text_tokens": 21, + "cache_write_tokens": 0, + "cache_creation_tokens": 0, + "cache_creation_token_details": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + }, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "service_tier": "standard", + }, + }, +) + + +CLAUDE_OPUS_5_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-opus-5-5", + "max_tokens": 64, + "messages": [ + {"role": "system", "content": "You are a terse assistant."}, + {"role": "user", "content": "Say hello."}, + ], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": [{"type": "text", "text": "Say hello."}]}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "anthropic_version": "bedrock-2023-05-31", + "model": "anthropic.claude-opus-5-5", + }, + mock_provider_response={ + "model": "claude-opus-5-5", + "id": "msg_bdrk_ynrmln5e2d6gulngkuay6eypqvjtghpnmtiioovu57numo6rag2q", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 23, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"thinking_tokens": 0}, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "id": ANY, + "created": ANY, + "model": "bedrock_mantle/anthropic.claude-opus-5-5", + "object": "chat.completion", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "Hello.", + "role": "assistant", + "provider_specific_fields": {"citations": None, "thinking_blocks": None}, + }, + } + ], + "usage": { + "completion_tokens": 6, + "prompt_tokens": 23, + "total_tokens": 29, + "completion_tokens_details": {"reasoning_tokens": 0, "text_tokens": 6}, + "prompt_tokens_details": { + "cached_tokens": 0, + "text_tokens": 23, + "cache_write_tokens": 0, + "cache_creation_tokens": 0, + "cache_creation_token_details": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + }, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "service_tier": "standard", + }, + }, +) + + +GPT_5_4_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.4", + "max_tokens": 64, + "messages": [ + {"role": "system", "content": "You are a terse assistant."}, + {"role": "user", "content": "Say hello."}, + ], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.4", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "stream": False, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240602, + "created_at": 1791240602, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_h5f65ggx7fstww26djcqgint5e7gwa2h6q43xjkxhggr2ftxybnq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.4", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello.", "type": "output_text"}], + "id": "msg_1abfa71ec4495d38a341706f85e7ef0b", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "none"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_h5f65ggx7fstww26djcqgint5e7gwa2h6q43xjkxhggr2ftxybnq", + "created": ANY, + "model": "bedrock_mantle/openai.gpt-5.4", + "object": "chat.completion", + "choices": [{"finish_reason": "stop", "index": 0, "message": {"content": "Hello.", "role": "assistant"}}], + "usage": { + "completion_tokens": 6, + "prompt_tokens": 19, + "total_tokens": 25, + "completion_tokens_details": {"reasoning_tokens": 0}, + "prompt_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0, "cache_creation_tokens": 0}, + }, + "billing": {"payer": "developer"}, + "frequency_penalty": 0.0, + "presence_penalty": 0.0, + "service_tier": "default", + }, +) + + +GPT_5_6_SOL_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.6-sol", + "max_tokens": 64, + "messages": [ + {"role": "system", "content": "You are a terse assistant."}, + {"role": "user", "content": "Say hello."}, + ], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.6-sol", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "stream": False, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240604, + "created_at": 1791240604, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_7s4e6m623k3hkjqx4fexvwqodxn3zxtfpkqrz4hdl7qe2wcyftsa", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.6-sol", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_d44132d374595fe789bdc2db8e00fdc0", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_7s4e6m623k3hkjqx4fexvwqodxn3zxtfpkqrz4hdl7qe2wcyftsa", + "created": ANY, + "model": "bedrock_mantle/openai.gpt-5.6-sol", + "object": "chat.completion", + "choices": [{"finish_reason": "stop", "index": 0, "message": {"content": "Hello!", "role": "assistant"}}], + "usage": { + "completion_tokens": 6, + "prompt_tokens": 19, + "total_tokens": 25, + "completion_tokens_details": {"reasoning_tokens": 0}, + "prompt_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0, "cache_creation_tokens": 0}, + }, + "billing": {"payer": "developer"}, + "frequency_penalty": 0.0, + "presence_penalty": 0.0, + "service_tier": "default", + }, +) + + +GPT_5_6_LUNA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.6-luna", + "max_tokens": 64, + "messages": [ + {"role": "system", "content": "You are a terse assistant."}, + {"role": "user", "content": "Say hello."}, + ], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.6-luna", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "stream": False, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240607, + "created_at": 1791240606, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_gnit33ia2bne452i37ag5m5jgatjnnqog5a25yjrymielrfwokra", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.6-luna", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_b216bd6781d252db9607a7b2c25af58f", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_gnit33ia2bne452i37ag5m5jgatjnnqog5a25yjrymielrfwokra", + "created": ANY, + "model": "bedrock_mantle/openai.gpt-5.6-luna", + "object": "chat.completion", + "choices": [{"finish_reason": "stop", "index": 0, "message": {"content": "Hello!", "role": "assistant"}}], + "usage": { + "completion_tokens": 6, + "prompt_tokens": 19, + "total_tokens": 25, + "completion_tokens_details": {"reasoning_tokens": 0}, + "prompt_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0, "cache_creation_tokens": 0}, + }, + "billing": {"payer": "developer"}, + "frequency_penalty": 0.0, + "presence_penalty": 0.0, + "service_tier": "default", + }, +) + + +GPT_6_LUNA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-6-luna", + "max_tokens": 64, + "messages": [ + {"role": "system", "content": "You are a terse assistant."}, + {"role": "user", "content": "Say hello."}, + ], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-6-luna", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "stream": False, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240609, + "created_at": 1791240609, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_y6jkekxfsn43teacrqd745fnw5m6l3q6sczasxu6y4nxmaoittxq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-6-luna", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_fb51254d3c005892a700f8dc8c55b04d", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_y6jkekxfsn43teacrqd745fnw5m6l3q6sczasxu6y4nxmaoittxq", + "created": ANY, + "model": "bedrock_mantle/openai.gpt-6-luna", + "object": "chat.completion", + "choices": [{"finish_reason": "stop", "index": 0, "message": {"content": "Hello!", "role": "assistant"}}], + "usage": { + "completion_tokens": 6, + "prompt_tokens": 19, + "total_tokens": 25, + "completion_tokens_details": {"reasoning_tokens": 0}, + "prompt_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0, "cache_creation_tokens": 0}, + }, + "billing": {"payer": "developer"}, + "frequency_penalty": 0.0, + "presence_penalty": 0.0, + "service_tier": "default", + }, +) + + +GPT_6_1_SOL_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-6.1-sol", + "max_tokens": 64, + "messages": [ + {"role": "system", "content": "You are a terse assistant."}, + {"role": "user", "content": "Say hello."}, + ], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-6.1-sol", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "stream": False, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240612, + "created_at": 1791240612, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_rjew7tdxw2lzv5egpmamwt2g5aifjxopahkpmzawjlcyucblokyq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-6.1-sol", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_6f7c19b0241956fda392424fc5aa3db9", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_rjew7tdxw2lzv5egpmamwt2g5aifjxopahkpmzawjlcyucblokyq", + "created": ANY, + "model": "bedrock_mantle/openai.gpt-6.1-sol", + "object": "chat.completion", + "choices": [{"finish_reason": "stop", "index": 0, "message": {"content": "Hello!", "role": "assistant"}}], + "usage": { + "completion_tokens": 6, + "prompt_tokens": 19, + "total_tokens": 25, + "completion_tokens_details": {"reasoning_tokens": 0}, + "prompt_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0, "cache_creation_tokens": 0}, + }, + "billing": {"payer": "developer"}, + "frequency_penalty": 0.0, + "presence_penalty": 0.0, + "service_tier": "default", + }, +) diff --git a/tests/integration/translation/chat_completions/basic/test_chat_completions_basic_bedrock_mantle.py b/tests/integration/translation/chat_completions/basic/test_chat_completions_basic_bedrock_mantle.py new file mode 100644 index 00000000000..32ecec11b15 --- /dev/null +++ b/tests/integration/translation/chat_completions/basic/test_chat_completions_basic_bedrock_mantle.py @@ -0,0 +1,35 @@ +import pytest +from integration._support.client import Gateway +from integration._support.provider import SharedProvider +from integration.translation.case import TranslationTestCase +from integration.translation.chat_completions.bases.bedrock_mantle import ( + CLAUDE_HAIKU_4_5_TEST_CASE, + CLAUDE_OPUS_5_5_TEST_CASE, + CLAUDE_SONNET_5_TEST_CASE, + GPT_5_4_TEST_CASE, + GPT_5_6_LUNA_TEST_CASE, + GPT_5_6_SOL_TEST_CASE, + GPT_6_1_SOL_TEST_CASE, + GPT_6_LUNA_TEST_CASE, +) +from integration.translation.runner import assert_translation + + +@pytest.mark.parametrize( + "case", + [ + CLAUDE_HAIKU_4_5_TEST_CASE, + CLAUDE_SONNET_5_TEST_CASE, + CLAUDE_OPUS_5_5_TEST_CASE, + GPT_5_4_TEST_CASE, + GPT_5_6_SOL_TEST_CASE, + GPT_5_6_LUNA_TEST_CASE, + GPT_6_LUNA_TEST_CASE, + GPT_6_1_SOL_TEST_CASE, + ], + ids=lambda case: case.id, +) +def test_chat_completions_basic_bedrock_mantle( + case: TranslationTestCase, gateway: Gateway, provider: SharedProvider +) -> None: + assert_translation(case, gateway, provider) diff --git a/tests/integration/translation/messages/bases/bedrock_mantle.py b/tests/integration/translation/messages/bases/bedrock_mantle.py new file mode 100644 index 00000000000..e932e03ad5e --- /dev/null +++ b/tests/integration/translation/messages/bases/bedrock_mantle.py @@ -0,0 +1,631 @@ +from typing import Final + +from integration.translation.case import TranslationTestCase + + +CLAUDE_HAIKU_4_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-haiku-4-5", + "max_tokens": 64, + "system": "You are a terse assistant.", + "messages": [{"role": "user", "content": "Say hello."}], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "anthropic-version": "2023-06-01", + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": "Say hello."}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "model": "anthropic.claude-haiku-4-5", + }, + mock_provider_response={ + "model": "claude-haiku-4-5-20251001", + "id": "msg_bdrk_vup3t4zou7dn7wcgq7cpekk5ra22doolpkubeg53d4nsr3e3nytq", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 17, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 5, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "model": "bedrock_mantle/anthropic.claude-haiku-4-5", + "id": "msg_bdrk_vup3t4zou7dn7wcgq7cpekk5ra22doolpkubeg53d4nsr3e3nytq", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 17, + "output_tokens": 5, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "service_tier": "standard", + }, + }, +) + + +CLAUDE_SONNET_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-sonnet-5", + "max_tokens": 64, + "system": "You are a terse assistant.", + "messages": [{"role": "user", "content": "Say hello."}], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "anthropic-version": "2023-06-01", + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": "Say hello."}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "model": "anthropic.claude-sonnet-5", + }, + mock_provider_response={ + "model": "claude-sonnet-5", + "id": "msg_bdrk_6vuplyqolvblp5dquv5mwrkdqbysmuymlyndmzjg2btbtdnavceq", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 21, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"thinking_tokens": 0}, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "model": "bedrock_mantle/anthropic.claude-sonnet-5", + "id": "msg_bdrk_6vuplyqolvblp5dquv5mwrkdqbysmuymlyndmzjg2btbtdnavceq", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 21, + "output_tokens": 6, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens_details": {"thinking_tokens": 0}, + "service_tier": "standard", + }, + }, +) + + +CLAUDE_OPUS_5_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-opus-5-5", + "max_tokens": 64, + "system": "You are a terse assistant.", + "messages": [{"role": "user", "content": "Say hello."}], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "anthropic-version": "2023-06-01", + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": "Say hello."}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "model": "anthropic.claude-opus-5-5", + }, + mock_provider_response={ + "model": "claude-opus-5-5", + "id": "msg_bdrk_52cr74cucwfccadhge37ynypl3e7cgfisudqlyjv4xyrjpa6j7ta", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 23, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"thinking_tokens": 0}, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "model": "bedrock_mantle/anthropic.claude-opus-5-5", + "id": "msg_bdrk_52cr74cucwfccadhge37ynypl3e7cgfisudqlyjv4xyrjpa6j7ta", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 23, + "output_tokens": 6, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens_details": {"thinking_tokens": 0}, + "service_tier": "standard", + }, + }, +) + + +GPT_5_4_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.4", + "max_tokens": 64, + "system": "You are a terse assistant.", + "messages": [{"role": "user", "content": "Say hello."}], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.4", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240601, + "created_at": 1791240601, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_mjtxgz2qvle22u6pbq4q54kmg2eeht2xgmplcgn4q43a4rxw6yia", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.4", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello.", "type": "output_text"}], + "id": "msg_73ae0510d47b58ac894fc429f4e37f57", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "none"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_mjtxgz2qvle22u6pbq4q54kmg2eeht2xgmplcgn4q43a4rxw6yia", + "type": "message", + "role": "assistant", + "model": "bedrock_mantle/openai.gpt-5.4", + "stop_sequence": None, + "usage": {"input_tokens": 19, "output_tokens": 6}, + "content": [{"type": "text", "text": "Hello."}], + "stop_reason": "end_turn", + "stop_details": None, + }, +) + + +GPT_5_6_SOL_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.6-sol", + "max_tokens": 64, + "system": "You are a terse assistant.", + "messages": [{"role": "user", "content": "Say hello."}], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.6-sol", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240604, + "created_at": 1791240603, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_7tsj6j6oi6de5rzq2lqrazvkayhfbtelrtb2x3sk7ozfu6xk2gfq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.6-sol", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_049815c6c03253f9983f121c752f04b4", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_7tsj6j6oi6de5rzq2lqrazvkayhfbtelrtb2x3sk7ozfu6xk2gfq", + "type": "message", + "role": "assistant", + "model": "bedrock_mantle/openai.gpt-5.6-sol", + "stop_sequence": None, + "usage": {"input_tokens": 19, "output_tokens": 6}, + "content": [{"type": "text", "text": "Hello!"}], + "stop_reason": "end_turn", + "stop_details": None, + }, +) + + +GPT_5_6_LUNA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.6-luna", + "max_tokens": 64, + "system": "You are a terse assistant.", + "messages": [{"role": "user", "content": "Say hello."}], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.6-luna", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240606, + "created_at": 1791240606, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_euq6yo6tnjzhkrw56ri24yqzcsr6yyt5k4a75ppn7iclefp34gxa", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.6-luna", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_765b9dcbdc385d74b07a4b93cd748e6c", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_euq6yo6tnjzhkrw56ri24yqzcsr6yyt5k4a75ppn7iclefp34gxa", + "type": "message", + "role": "assistant", + "model": "bedrock_mantle/openai.gpt-5.6-luna", + "stop_sequence": None, + "usage": {"input_tokens": 19, "output_tokens": 6}, + "content": [{"type": "text", "text": "Hello!"}], + "stop_reason": "end_turn", + "stop_details": None, + }, +) + + +GPT_6_LUNA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-6-luna", + "max_tokens": 64, + "system": "You are a terse assistant.", + "messages": [{"role": "user", "content": "Say hello."}], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-6-luna", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240608, + "created_at": 1791240608, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_o2at36wcxwspffhlmvydms2hpl24bse46blsmsm52ov4xtt4ordq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-6-luna", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_333c149682be50c9b9baebeecbee8f18", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_o2at36wcxwspffhlmvydms2hpl24bse46blsmsm52ov4xtt4ordq", + "type": "message", + "role": "assistant", + "model": "bedrock_mantle/openai.gpt-6-luna", + "stop_sequence": None, + "usage": {"input_tokens": 19, "output_tokens": 6}, + "content": [{"type": "text", "text": "Hello!"}], + "stop_reason": "end_turn", + "stop_details": None, + }, +) + + +GPT_6_1_SOL_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-6.1-sol", + "max_tokens": 64, + "system": "You are a terse assistant.", + "messages": [{"role": "user", "content": "Say hello."}], + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-6.1-sol", + "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Say hello."}]}], + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240611, + "created_at": 1791240611, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_o2fd3mpsaqp564aclj3nmh5776564wp3h5ljwc4dsjgjfncqvonq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-6.1-sol", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_597e5fe9c0fd506dae6deaac23093e3d", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": "resp_o2fd3mpsaqp564aclj3nmh5776564wp3h5ljwc4dsjgjfncqvonq", + "type": "message", + "role": "assistant", + "model": "bedrock_mantle/openai.gpt-6.1-sol", + "stop_sequence": None, + "usage": {"input_tokens": 19, "output_tokens": 6}, + "content": [{"type": "text", "text": "Hello!"}], + "stop_reason": "end_turn", + "stop_details": None, + }, +) diff --git a/tests/integration/translation/messages/basic/test_messages_basic_bedrock_mantle.py b/tests/integration/translation/messages/basic/test_messages_basic_bedrock_mantle.py new file mode 100644 index 00000000000..80a55d9eb35 --- /dev/null +++ b/tests/integration/translation/messages/basic/test_messages_basic_bedrock_mantle.py @@ -0,0 +1,33 @@ +import pytest +from integration._support.client import Gateway +from integration._support.provider import SharedProvider +from integration.translation.case import TranslationTestCase +from integration.translation.messages.bases.bedrock_mantle import ( + CLAUDE_HAIKU_4_5_TEST_CASE, + CLAUDE_OPUS_5_5_TEST_CASE, + CLAUDE_SONNET_5_TEST_CASE, + GPT_5_4_TEST_CASE, + GPT_5_6_LUNA_TEST_CASE, + GPT_5_6_SOL_TEST_CASE, + GPT_6_1_SOL_TEST_CASE, + GPT_6_LUNA_TEST_CASE, +) +from integration.translation.runner import assert_translation + + +@pytest.mark.parametrize( + "case", + [ + CLAUDE_HAIKU_4_5_TEST_CASE, + CLAUDE_SONNET_5_TEST_CASE, + CLAUDE_OPUS_5_5_TEST_CASE, + GPT_5_4_TEST_CASE, + GPT_5_6_SOL_TEST_CASE, + GPT_5_6_LUNA_TEST_CASE, + GPT_6_LUNA_TEST_CASE, + GPT_6_1_SOL_TEST_CASE, + ], + ids=lambda case: case.id, +) +def test_messages_basic_bedrock_mantle(case: TranslationTestCase, gateway: Gateway, provider: SharedProvider) -> None: + assert_translation(case, gateway, provider) diff --git a/tests/integration/translation/responses/bases/bedrock_mantle.py b/tests/integration/translation/responses/bases/bedrock_mantle.py new file mode 100644 index 00000000000..6864930178d --- /dev/null +++ b/tests/integration/translation/responses/bases/bedrock_mantle.py @@ -0,0 +1,973 @@ +from typing import Final +from unittest.mock import ANY + +from integration.translation.case import TranslationTestCase + + +CLAUDE_HAIKU_4_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-haiku-4-5", + "max_output_tokens": 64, + "instructions": "You are a terse assistant.", + "input": "Say hello.", + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": [{"type": "text", "text": "Say hello."}]}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "anthropic_version": "bedrock-2023-05-31", + "model": "anthropic.claude-haiku-4-5", + }, + mock_provider_response={ + "model": "claude-haiku-4-5-20251001", + "id": "msg_bdrk_lml4zvpzgxmbosxxxmuorjfiiq4indaswznwruho3redh7eijusq", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello!"}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 17, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 5, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "id": ANY, + "created_at": ANY, + "error": None, + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "metadata": {}, + "model": "bedrock_mantle/anthropic.claude-haiku-4-5", + "object": "response", + "output": [ + { + "type": "message", + "id": ANY, + "status": "completed", + "role": "assistant", + "content": [{"type": "output_text", "text": "Hello!", "annotations": []}], + "phase": None, + } + ], + "parallel_tool_calls": False, + "temperature": None, + "tool_choice": "auto", + "tools": [], + "top_p": None, + "max_output_tokens": 64, + "previous_response_id": None, + "reasoning": None, + "status": "completed", + "text": {}, + "truncation": None, + "usage": { + "input_tokens": 17, + "input_tokens_details": { + "audio_tokens": None, + "cached_tokens": 0, + "cached_tokens_details": None, + "image_tokens": None, + "text_tokens": 17, + "video_tokens": None, + "cache_write_tokens": 0, + }, + "output_tokens": 5, + "output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 0, "text_tokens": 5}, + "total_tokens": 22, + "cost": None, + }, + "user": None, + "store": None, + "provider_specific_fields": {"citations": None, "thinking_blocks": None}, + }, +) + + +CLAUDE_SONNET_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-sonnet-5", + "max_output_tokens": 64, + "instructions": "You are a terse assistant.", + "input": "Say hello.", + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": [{"type": "text", "text": "Say hello."}]}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "anthropic_version": "bedrock-2023-05-31", + "model": "anthropic.claude-sonnet-5", + }, + mock_provider_response={ + "model": "claude-sonnet-5", + "id": "msg_bdrk_73xk5vorp6t4tog7jvr6e6ohck6mykwzj3sv5qwnkil2d2tdoftq", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 21, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"thinking_tokens": 0}, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "id": ANY, + "created_at": ANY, + "error": None, + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "metadata": {}, + "model": "bedrock_mantle/anthropic.claude-sonnet-5", + "object": "response", + "output": [ + { + "type": "message", + "id": ANY, + "status": "completed", + "role": "assistant", + "content": [{"type": "output_text", "text": "Hello.", "annotations": []}], + "phase": None, + } + ], + "parallel_tool_calls": False, + "temperature": None, + "tool_choice": "auto", + "tools": [], + "top_p": None, + "max_output_tokens": 64, + "previous_response_id": None, + "reasoning": None, + "status": "completed", + "text": {}, + "truncation": None, + "usage": { + "input_tokens": 21, + "input_tokens_details": { + "audio_tokens": None, + "cached_tokens": 0, + "cached_tokens_details": None, + "image_tokens": None, + "text_tokens": 21, + "video_tokens": None, + "cache_write_tokens": 0, + }, + "output_tokens": 6, + "output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 0, "text_tokens": 6}, + "total_tokens": 27, + "cost": None, + }, + "user": None, + "store": None, + "provider_specific_fields": {"citations": None, "thinking_blocks": None}, + }, +) + + +CLAUDE_OPUS_5_5_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={ + "model": "bedrock_mantle/anthropic.claude-opus-5-5", + "max_output_tokens": 64, + "instructions": "You are a terse assistant.", + "input": "Say hello.", + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/anthropic/v1/messages", + expected_provider_headers={ + "content-type": "application/json", + "authorization": "Bearer synthetic-bedrock-mantle-key", + }, + expected_provider_request={ + "messages": [{"role": "user", "content": [{"type": "text", "text": "Say hello."}]}], + "max_tokens": 64, + "system": [{"type": "text", "text": "You are a terse assistant."}], + "anthropic_version": "bedrock-2023-05-31", + "model": "anthropic.claude-opus-5-5", + }, + mock_provider_response={ + "model": "claude-opus-5-5", + "id": "msg_bdrk_tcemmkaonjjx6pb7gr76umjdqmuwgte56kvf6itwjylegy4lpc3a", + "type": "message", + "role": "assistant", + "content": [{"type": "text", "text": "Hello."}], + "container": None, + "stop_reason": "end_turn", + "stop_sequence": None, + "stop_details": None, + "usage": { + "input_tokens": 23, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"thinking_tokens": 0}, + "service_tier": "standard", + }, + }, + expected_litellm_response={ + "id": ANY, + "created_at": ANY, + "error": None, + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "metadata": {}, + "model": "bedrock_mantle/anthropic.claude-opus-5-5", + "object": "response", + "output": [ + { + "type": "message", + "id": ANY, + "status": "completed", + "role": "assistant", + "content": [{"type": "output_text", "text": "Hello.", "annotations": []}], + "phase": None, + } + ], + "parallel_tool_calls": False, + "temperature": None, + "tool_choice": "auto", + "tools": [], + "top_p": None, + "max_output_tokens": 64, + "previous_response_id": None, + "reasoning": None, + "status": "completed", + "text": {}, + "truncation": None, + "usage": { + "input_tokens": 23, + "input_tokens_details": { + "audio_tokens": None, + "cached_tokens": 0, + "cached_tokens_details": None, + "image_tokens": None, + "text_tokens": 23, + "video_tokens": None, + "cache_write_tokens": 0, + }, + "output_tokens": 6, + "output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 0, "text_tokens": 6}, + "total_tokens": 29, + "cost": None, + }, + "user": None, + "store": None, + "provider_specific_fields": {"citations": None, "thinking_blocks": None}, + }, +) + + +GPT_5_4_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.4", + "max_output_tokens": 64, + "instructions": "You are a terse assistant.", + "input": "Say hello.", + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.4", + "input": "Say hello.", + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240603, + "created_at": 1791240603, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_6n4dcdfylvtcf4gs5xi7cbqt6sacvcyafrmdt2dm4m32g2jzjsca", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.4", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello.", "type": "output_text"}], + "id": "msg_76cc325cb949522da46846872f930337", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "none"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": ANY, + "created_at": 1791240603, + "error": None, + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "metadata": {}, + "model": "bedrock_mantle/openai.gpt-5.4", + "object": "response", + "output": [ + { + "id": "msg_76cc325cb949522da46846872f930337", + "content": [{"annotations": [], "text": "Hello.", "type": "output_text", "logprobs": []}], + "role": "assistant", + "status": "completed", + "type": "message", + "phase": "final_answer", + } + ], + "parallel_tool_calls": True, + "temperature": 1.0, + "tool_choice": "auto", + "tools": [], + "top_p": 0.98, + "max_output_tokens": 64, + "previous_response_id": None, + "reasoning": {"summary": None, "effort": "none"}, + "status": "completed", + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": { + "audio_tokens": None, + "cached_tokens": 0, + "cached_tokens_details": None, + "image_tokens": None, + "text_tokens": None, + "video_tokens": None, + "cache_write_tokens": 0, + }, + "output_tokens": 6, + "output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 0, "text_tokens": None}, + "total_tokens": 25, + "cost": None, + }, + "user": None, + "store": True, + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240603, + "frequency_penalty": 0.0, + "max_tool_calls": None, + "presence_penalty": 0.0, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "safety_identifier": None, + "service_tier": "default", + "top_logprobs": 0, + "moderation": None, + }, +) + + +GPT_5_6_SOL_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.6-sol", + "max_output_tokens": 64, + "instructions": "You are a terse assistant.", + "input": "Say hello.", + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.6-sol", + "input": "Say hello.", + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240605, + "created_at": 1791240605, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_a5onvds4tvin6cax2b2sxhhbc3l26ktf72r6eybmzvc5yjvouwaq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.6-sol", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_453083c06537503e98fd06ef5f4695cb", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": ANY, + "created_at": 1791240605, + "error": None, + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "metadata": {}, + "model": "bedrock_mantle/openai.gpt-5.6-sol", + "object": "response", + "output": [ + { + "id": "msg_453083c06537503e98fd06ef5f4695cb", + "content": [{"annotations": [], "text": "Hello!", "type": "output_text", "logprobs": []}], + "role": "assistant", + "status": "completed", + "type": "message", + "phase": "final_answer", + } + ], + "parallel_tool_calls": True, + "temperature": 1.0, + "tool_choice": "auto", + "tools": [], + "top_p": 0.98, + "max_output_tokens": 64, + "previous_response_id": None, + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "status": "completed", + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": { + "audio_tokens": None, + "cached_tokens": 0, + "cached_tokens_details": None, + "image_tokens": None, + "text_tokens": None, + "video_tokens": None, + "cache_write_tokens": 0, + }, + "output_tokens": 6, + "output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 0, "text_tokens": None}, + "total_tokens": 25, + "cost": None, + }, + "user": None, + "store": True, + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240605, + "frequency_penalty": 0.0, + "max_tool_calls": None, + "presence_penalty": 0.0, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "safety_identifier": None, + "service_tier": "default", + "top_logprobs": 0, + "moderation": None, + }, +) + + +GPT_5_6_LUNA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-5.6-luna", + "max_output_tokens": 64, + "instructions": "You are a terse assistant.", + "input": "Say hello.", + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-5.6-luna", + "input": "Say hello.", + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240608, + "created_at": 1791240607, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_byjr6m3dzer75kvjrtcr3x7koxglybfni6zmcdndptl7zi5pdyuq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-5.6-luna", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_e9993690dc1f5411be17b63ff2b0e8e9", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": ANY, + "created_at": 1791240607, + "error": None, + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "metadata": {}, + "model": "bedrock_mantle/openai.gpt-5.6-luna", + "object": "response", + "output": [ + { + "id": "msg_e9993690dc1f5411be17b63ff2b0e8e9", + "content": [{"annotations": [], "text": "Hello!", "type": "output_text", "logprobs": []}], + "role": "assistant", + "status": "completed", + "type": "message", + "phase": "final_answer", + } + ], + "parallel_tool_calls": True, + "temperature": 1.0, + "tool_choice": "auto", + "tools": [], + "top_p": 0.98, + "max_output_tokens": 64, + "previous_response_id": None, + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "status": "completed", + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": { + "audio_tokens": None, + "cached_tokens": 0, + "cached_tokens_details": None, + "image_tokens": None, + "text_tokens": None, + "video_tokens": None, + "cache_write_tokens": 0, + }, + "output_tokens": 6, + "output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 0, "text_tokens": None}, + "total_tokens": 25, + "cost": None, + }, + "user": None, + "store": True, + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240608, + "frequency_penalty": 0.0, + "max_tool_calls": None, + "presence_penalty": 0.0, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "safety_identifier": None, + "service_tier": "default", + "top_logprobs": 0, + "moderation": None, + }, +) + + +GPT_6_LUNA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-6-luna", + "max_output_tokens": 64, + "instructions": "You are a terse assistant.", + "input": "Say hello.", + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-6-luna", + "input": "Say hello.", + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240610, + "created_at": 1791240610, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_cazpgby3iulwndtqlxaczoyacnql23jugwncarclttip7ewos6na", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-6-luna", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_f693bb420fad55468f26ef3b43e761fd", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": ANY, + "created_at": 1791240610, + "error": None, + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "metadata": {}, + "model": "bedrock_mantle/openai.gpt-6-luna", + "object": "response", + "output": [ + { + "id": "msg_f693bb420fad55468f26ef3b43e761fd", + "content": [{"annotations": [], "text": "Hello!", "type": "output_text", "logprobs": []}], + "role": "assistant", + "status": "completed", + "type": "message", + "phase": "final_answer", + } + ], + "parallel_tool_calls": True, + "temperature": 1.0, + "tool_choice": "auto", + "tools": [], + "top_p": 0.98, + "max_output_tokens": 64, + "previous_response_id": None, + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "status": "completed", + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": { + "audio_tokens": None, + "cached_tokens": 0, + "cached_tokens_details": None, + "image_tokens": None, + "text_tokens": None, + "video_tokens": None, + "cache_write_tokens": 0, + }, + "output_tokens": 6, + "output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 0, "text_tokens": None}, + "total_tokens": 25, + "cost": None, + }, + "user": None, + "store": True, + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240610, + "frequency_penalty": 0.0, + "max_tool_calls": None, + "presence_penalty": 0.0, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "safety_identifier": None, + "service_tier": "default", + "top_logprobs": 0, + "moderation": None, + }, +) + + +GPT_6_1_SOL_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={ + "model": "bedrock_mantle/openai.gpt-6.1-sol", + "max_output_tokens": 64, + "instructions": "You are a terse assistant.", + "input": "Say hello.", + "cache": {"no-cache": True}, + }, + expected_provider_endpoint="/openai/v1/responses", + expected_provider_headers={ + "authorization": "Bearer synthetic-bedrock-mantle-key", + "content-type": "application/json", + }, + expected_provider_request={ + "model": "openai.gpt-6.1-sol", + "input": "Say hello.", + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + }, + mock_provider_response={ + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240614, + "created_at": 1791240613, + "error": None, + "frequency_penalty": 0.0, + "id": "resp_gt7xddo5iwmhm7nsml7dsko5lwptca2telb6kmivpwlm7hvjospq", + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "max_output_tokens": 64, + "max_tool_calls": None, + "metadata": {}, + "model": "openai.gpt-6.1-sol", + "object": "response", + "output": [ + { + "content": [{"annotations": [], "logprobs": [], "text": "Hello!", "type": "output_text"}], + "id": "msg_b6510810920854d29a290136d5eb08b1", + "phase": "final_answer", + "role": "assistant", + "status": "completed", + "type": "message", + } + ], + "parallel_tool_calls": True, + "presence_penalty": 0.0, + "previous_response_id": None, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "safety_identifier": None, + "service_tier": "default", + "status": "completed", + "store": True, + "temperature": 1.0, + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "tool_choice": "auto", + "tools": [], + "top_logprobs": 0, + "top_p": 0.98, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}, + "output_tokens": 6, + "output_tokens_details": {"reasoning_tokens": 0}, + "total_tokens": 25, + }, + "user": None, + "moderation": None, + }, + expected_litellm_response={ + "id": ANY, + "created_at": 1791240613, + "error": None, + "incomplete_details": None, + "instructions": "You are a terse assistant.", + "metadata": {}, + "model": "bedrock_mantle/openai.gpt-6.1-sol", + "object": "response", + "output": [ + { + "id": "msg_b6510810920854d29a290136d5eb08b1", + "content": [{"annotations": [], "text": "Hello!", "type": "output_text", "logprobs": []}], + "role": "assistant", + "status": "completed", + "type": "message", + "phase": "final_answer", + } + ], + "parallel_tool_calls": True, + "temperature": 1.0, + "tool_choice": "auto", + "tools": [], + "top_p": 0.98, + "max_output_tokens": 64, + "previous_response_id": None, + "reasoning": {"summary": None, "effort": "medium", "context": "all_turns"}, + "status": "completed", + "text": {"format": {"type": "text"}, "verbosity": "medium"}, + "truncation": "disabled", + "usage": { + "input_tokens": 19, + "input_tokens_details": { + "audio_tokens": None, + "cached_tokens": 0, + "cached_tokens_details": None, + "image_tokens": None, + "text_tokens": None, + "video_tokens": None, + "cache_write_tokens": 0, + }, + "output_tokens": 6, + "output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 0, "text_tokens": None}, + "total_tokens": 25, + "cost": None, + }, + "user": None, + "store": True, + "background": False, + "billing": {"payer": "developer"}, + "completed_at": 1791240614, + "frequency_penalty": 0.0, + "max_tool_calls": None, + "presence_penalty": 0.0, + "prompt_cache_key": None, + "prompt_cache_retention": "in_memory", + "safety_identifier": None, + "service_tier": "default", + "top_logprobs": 0, + "moderation": None, + }, +) diff --git a/tests/integration/translation/responses/basic/test_responses_basic_bedrock_mantle.py b/tests/integration/translation/responses/basic/test_responses_basic_bedrock_mantle.py new file mode 100644 index 00000000000..fc4a7289adb --- /dev/null +++ b/tests/integration/translation/responses/basic/test_responses_basic_bedrock_mantle.py @@ -0,0 +1,33 @@ +import pytest +from integration._support.client import Gateway +from integration._support.provider import SharedProvider +from integration.translation.case import TranslationTestCase +from integration.translation.responses.bases.bedrock_mantle import ( + CLAUDE_HAIKU_4_5_TEST_CASE, + CLAUDE_OPUS_5_5_TEST_CASE, + CLAUDE_SONNET_5_TEST_CASE, + GPT_5_4_TEST_CASE, + GPT_5_6_LUNA_TEST_CASE, + GPT_5_6_SOL_TEST_CASE, + GPT_6_1_SOL_TEST_CASE, + GPT_6_LUNA_TEST_CASE, +) +from integration.translation.runner import assert_translation + + +@pytest.mark.parametrize( + "case", + [ + CLAUDE_HAIKU_4_5_TEST_CASE, + CLAUDE_SONNET_5_TEST_CASE, + CLAUDE_OPUS_5_5_TEST_CASE, + GPT_5_4_TEST_CASE, + GPT_5_6_SOL_TEST_CASE, + GPT_5_6_LUNA_TEST_CASE, + GPT_6_LUNA_TEST_CASE, + GPT_6_1_SOL_TEST_CASE, + ], + ids=lambda case: case.id, +) +def test_responses_basic_bedrock_mantle(case: TranslationTestCase, gateway: Gateway, provider: SharedProvider) -> None: + assert_translation(case, gateway, provider)