diff --git a/tests/integration/translation/chat_completions/bases/openai.py b/tests/integration/translation/chat_completions/bases/openai.py index 25d8121cf31..355e01be180 100644 --- a/tests/integration/translation/chat_completions/bases/openai.py +++ b/tests/integration/translation/chat_completions/bases/openai.py @@ -451,6 +451,7 @@ GPT_6_LUNA_TEST_CASE: Final = TranslationTestCase( ) + GPT_5_MINI_TEST_CASE: Final = TranslationTestCase( scenario="agent_tools", litellm_endpoint="/v1/chat/completions", @@ -1235,3 +1236,276 @@ GPT_5_6_TERRA_TEST_CASE: Final = TranslationTestCase( }, }, ) + + +GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE: Final = { + 'id': 'resp_0b85038a4a37efb6006ae75c0cf84c87d1ac49e75264e5701f', + 'object': 'response', + 'created_at': 1793547277, + 'status': 'completed', + 'access_programs': { + 'cyber': 'standard', + }, + 'background': False, + 'billing': { + 'payer': 'developer', + }, + 'completed_at': 1793547279, + 'error': None, + 'frequency_penalty': 0.0, + 'incomplete_details': None, + 'instructions': ( + 'You help maintain a synthetic Python project. Read the relevant files before suggesting ' + 'a fix. Explain which file you need next, then call a read-only tool. Never change files.' + ' Use the chat_completions client for this project review. Consider zero, negative and no' + 'n-integer quantities before choosing the next file to inspect.' + ), + 'max_output_tokens': 1024, + 'max_tool_calls': None, + 'model': 'gpt-6.1-terra', + 'moderation': None, + 'output': [ + { + 'id': 'rs_0b85038a4a37efb6006ae75c0de1ac87d1a40d2ce0476272d9', + 'type': 'reasoning', + 'content': [], + 'encrypted_content': ( + 'gAAAAABq51wPWhH43zwDEF4VgA1Kgnfi13a_k7Ff26kP_ipp7PFCxc9W_3tlMScFQVruAcFY4-QJk3WYSiz_ErCS' + 'n7_u9vSRN1KB6ytyA4CMads8YIpqomBsURrtDZKtt26D2sp9DgthN5hg4sMsAiuOGkhNWwQ91cXOv6YXmKRQ3nTX' + 'ZhMXy07iuYELaE10_tszlQ6ZG0Etml2Ka59Y_Rod-NQHRtWSfowQrqhaYgwDimAMfuVdOo4myHtwIAWT8O4I2oAH' + 'BwXm2LcKPUh7DcUBNvdrqTSO9YfgFpmc82-y5xaHYcRd2nM0s5_AaQfISy1LANBI7l5yY-D_FxxISG6zyzOagbLO' + 'lLhdP3ftLpwAqu_xp13sJELtUR0r3itiDRxllGU9r0oIQ3b8bu3Z0bOH-1WWRBTEBUVCeDSadRIpa-gRJhZ-DSir' + 'wvZbqpZrKhn7LtaW0wgQlwuUZUCGk7MxdTrKe7Zw7K86iXY39outrZ4JACMUx5bez-_O0WVyuvjeIWAHKCSH9ofj' + 'bZXjPpG6mKaIggIGw8nZBr_uy60TVTvWvodJPoJ50lEDoi0ZClDgtQol7ypWSKBIVViuNMgHp27n4BFlGfl57Aef' + 'nD3PzqHFUNCawiH56wP1YgcsrwnlFCPKkFfgZHTGj190Rg8gTFRpOYfNLrI65AIR6LrUY091yqwAfifk3iyh5qy7' + 'YGtNyYw0IGTV3OYKoQJWCi3Pct6f9tNUenTtq7e-UT0OxVQxe_yyBPTm73TthwygwTSVczQ25q49Buzu7Dk7YWAw' + 'AvKGfvT9dqn7MsAV37PjBYTeRjZr23uNHIyPc8wHx5gq_1czCRDASUx6rEhQQzcvhG79ru2_apH61JWAYiVnfBAT' + 'zsvfabELZ9xdZxiY_p30L4AQKaV4MGPfYuqlKWpY3mxRUGjqres5KqVd5-rGWsfm4xlPYQpRnnKcNbEd1gNfDdc2' + 'IQUBmRB9zMVszhvWTFleLJrd84ztACnuC8DKxFSxihZ8QDKJbIEMqpYqm6ZUCljweUI--f9nYaoX9OIl5ch4tPoq' + '7SVRdG1pxfAo7RubrgAYNiACntgbhpF8Wf9wWbXTxgBco4QvtdeEqEm6Fp--fK5uMvf2aUXL8mCda8Z-KZBWlO1v' + '4xh8cHRJOkIU0rWNLYaPpmmEq109oL6B3gmSe7xrkAzhsD5ITBziXgZZvxY4r34JfLlBWRrx_1sEqFNTCtuaibVZ' + 'ZK15AysbTmMlumjfkP-tC8ygdtqJfSUUsVFzxgf8z6ThoP0MeMeuOKA79VeHpCnl758U80BIeUicDBBwwYIP8kpU' + 'ZyGqUTZcxDNQ80U9mXYMErrDf0PnzisTpw2Tm6gytBdjKfH07P272VfNJYHsO53l7oOkyUS1e9OdeWBEMaDje1B0' + 'QITl4-laHjbXnMIdZUdsxWTTiCljzzQQVoN8nQASBTvw-QJNFMqjAyBOt02bvCOVh7Jb9VJrTpXmVZKZ2HDHccma' + '7EohOL0qklhQ6EXxPdn_Gs3-9pGESbfOFZaf01A6gH7iznMxRUMVYAUl4yqr8PFGpA-uEljFhScorVtN1Rm5QUGA' + 'qiCMUnVjeb40_swu8wlC5y7liGJXEiq0zo0wgrn_HU3FZXmWXbBHAkCWlFt8pz2CPIMNLUvc4HaN8Xlcq6kK2aX5' + 'OH_Q8tVUsIS_0SpoAjWVc-6V9a7veqoik2yQyujvjw0b9sESo9qyZeiYj0M73v6SqBfjW2ACTZk5v9V5xLYgjOxZ' + 'Pe-XALR50X3B0FEalWUkUC-uv0scJcHYxb8k2n21OPr4F0Lb01gdTFyk9cbfXyJH5WCc-TGYlmCk3izsNRrWyYNo' + 'g8y77dkxKMjQRGrut-bU6jpu6ctDfOcgTVC-q6sKXURqfNQfP_1ZRCmDApKn3tuTt0vVahZOIJF3rGjvy5bzjyWA' + 'LBqxnsMxeLEEZnjfzqwG6ElioJjN5tHf4MJFV3I4aCmtSOGsaWfdF8_sYSwZ48Q16UO_-BzE_dE2W2wOQZ2inbut' + 'IhUU3r-ga_ogGlntLMJ2GD2r2OgCHJ59PHgL-nOnrbfQdZ_sXmcovUnQiAjKuFAx48cQEZ-i74QAbaCgmUFdrDue' + '_oWlk76IWXR15mwWLbpBZMR5aG4WREsvroJ17mIabFGi7R2_f7Vpe401W04gqDQjgxhkN0zY4rwBCmWZg6YJNntz' + 'qgIWoOcc9ZKUEOh-bpyhoWIyFIgtm4YlQQT-nDJwfRt7CCAz9LwTlx8czHn7JoIR4Oj6-fFY06ILYPmn8TOFFCQb' + 'ZcbdfY-NCE9TU1G60AHddQllarXRSxL4J-MN9tQhk22Ib-cPpGgtSL3L2-12zs0O3SiNUisxdaEEUZpaxauuAu38' + 'TH1_pelomrwvCdE1ukyyQBKDGJkxf4PxUy298fsg0-RQgALmaKa_ZWl68o5weQyPz-phC9GLjwUCgaKzijoI3fec' + 'Low1EDYkbCmkGFJhBiaAsl-AexuSKgFwKvTAg-O1R4SYPRShr6laHfzP9A5VC2hrcQ==' + ), + 'summary': [], + }, + { + 'id': 'msg_0b85038a4a37efb6006ae75c0ec8b887d1b503c5d0835acef1', + 'type': 'message', + 'status': 'completed', + 'content': [ + { + 'type': 'output_text', + 'annotations': [], + 'logprobs': [], + 'text': ( + 'I’ll read `shop/validation.py` first to check how it handles zero, negative, and non-int' + 'eger quantities.' + ), + }, + ], + 'phase': 'commentary', + 'role': 'assistant', + }, + { + 'id': 'fc_0b85038a4a37efb6006ae75c0f3af487d1ade6d1cb6b7aab90', + 'type': 'function_call', + 'status': 'completed', + 'arguments': '{"path":"shop/validation.py","start_line":1,"end_line":200}', + 'call_id': 'call_AJa3dZ4npr0KPN0SEwwl90xc', + 'name': 'read_file', + }, + ], + 'parallel_tool_calls': True, + 'presence_penalty': 0.0, + 'previous_response_id': None, + 'prompt_cache_key': None, + 'prompt_cache_retention': '24h', + 'reasoning': { + 'context': 'all_turns', + 'effort': 'high', + 'mode': 'standard', + 'summary': None, + }, + 'safety_identifier': None, + 'service_tier': 'default', + 'store': True, + 'temperature': 1.0, + 'text': { + 'format': { + 'type': 'text', + }, + 'verbosity': 'medium', + }, + 'tool_choice': 'auto', + 'tool_usage': { + 'image_gen': { + 'input_tokens': 0, + 'input_tokens_details': { + 'image_tokens': 0, + 'text_tokens': 0, + }, + 'output_tokens': 0, + 'output_tokens_details': { + 'image_tokens': 0, + 'text_tokens': 0, + }, + 'total_tokens': 0, + }, + 'web_search': { + 'num_requests': 0, + }, + }, + 'tools': [ + { + 'type': 'function', + 'description': 'Search source and test files for a literal term.', + 'name': 'search_files', + 'output_schema': None, + 'parameters': { + 'type': 'object', + 'properties': { + 'query': { + 'type': 'string', + }, + 'paths': { + 'type': 'array', + 'items': { + 'type': 'string', + }, + }, + }, + 'required': [ + 'query', + 'paths', + ], + 'additionalProperties': False, + }, + 'strict': False, + }, + { + 'type': 'function', + 'description': 'Read a range of lines from a project file.', + 'name': 'read_file', + 'output_schema': None, + 'parameters': { + 'type': 'object', + 'properties': { + 'path': { + 'type': 'string', + }, + 'start_line': { + 'type': 'integer', + 'minimum': 1, + }, + 'end_line': { + 'type': 'integer', + 'minimum': 1, + }, + }, + 'required': [ + 'path', + 'start_line', + 'end_line', + ], + 'additionalProperties': False, + }, + 'strict': False, + }, + ], + 'top_logprobs': 0, + 'top_p': 0.98, + 'truncation': 'disabled', + 'usage': { + 'input_tokens': 312, + 'input_tokens_details': { + 'cache_write_tokens': 0, + 'cached_tokens': 0, + }, + 'output_tokens': 144, + 'output_tokens_details': { + 'reasoning_tokens': 79, + }, + 'total_tokens': 456, + }, + 'user': None, + 'metadata': {}, +} + +GPT_6_1_TERRA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/chat/completions", + litellm_request={**CHAT_COMPLETIONS_REQUEST, "model": "openai/gpt-6.1-terra"}, + expected_provider_endpoint="/responses", + expected_provider_headers=GPT_5_6_TERRA_TEST_CASE.expected_provider_headers, + expected_provider_request={ + **OPENAI_RESPONSES_REQUEST_FROM_CHAT_COMPLETIONS, + "model": "gpt-6.1-terra", + }, + mock_provider_response=GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE, + expected_litellm_response={ + **GPT_5_6_TERRA_TEST_CASE.expected_litellm_response, + "id": "resp_0b85038a4a37efb6006ae75c0cf84c87d1ac49e75264e5701f", + "model": "openai/gpt-6.1-terra", + "choices": [ + { + "finish_reason": "tool_calls", + "index": 0, + "message": { + "content": "I’ll read `shop/validation.py` first to check how it handles zero, negative, and non-integer quantities.", + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "function": { + "arguments": '{"path":"shop/validation.py","start_line":1,"end_line":200}', + "name": "read_file", + }, + "id": "call_AJa3dZ4npr0KPN0SEwwl90xc", + "type": "function", + } + ], + "reasoning_items": [ + { + "type": "reasoning", + "id": "rs_0b85038a4a37efb6006ae75c0de1ac87d1a40d2ce0476272d9", + "encrypted_content": GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE["output"][0][ + "encrypted_content" + ], + "summary": [], + } + ], + "provider_specific_fields": { + "phase": "commentary", + "openai_responses_replay": ANY, + }, + }, + } + ], + "usage": { + "completion_tokens": 144, + "prompt_tokens": 312, + "total_tokens": 456, + "completion_tokens_details": {"reasoning_tokens": 79}, + "prompt_tokens_details": { + "cached_tokens": 0, + "cache_write_tokens": 0, + "cache_creation_tokens": 0, + }, + }, + "access_programs": {"cyber": "standard"}, + }, +) diff --git a/tests/integration/translation/chat_completions/basic/test_chat_completions_basic_openai.py b/tests/integration/translation/chat_completions/basic/test_chat_completions_basic_openai.py index b6a60721b65..11b14249af7 100644 --- a/tests/integration/translation/chat_completions/basic/test_chat_completions_basic_openai.py +++ b/tests/integration/translation/chat_completions/basic/test_chat_completions_basic_openai.py @@ -7,6 +7,7 @@ from integration.translation.chat_completions.bases.openai import ( GPT_5_6_LUNA_TEST_CASE, GPT_5_6_SOL_TEST_CASE, GPT_5_6_TERRA_TEST_CASE, + GPT_6_1_TERRA_TEST_CASE, GPT_6_1_SOL_TEST_CASE, GPT_6_ASTRA_TEST_CASE, GPT_6_LUNA_TEST_CASE, @@ -24,6 +25,7 @@ from integration.translation.runner import assert_translation GPT_6_1_SOL_TEST_CASE, GPT_6_ASTRA_TEST_CASE, GPT_5_6_TERRA_TEST_CASE, + GPT_6_1_TERRA_TEST_CASE, ], ids=lambda case: case.id, ) diff --git a/tests/integration/translation/messages/bases/openai.py b/tests/integration/translation/messages/bases/openai.py index f53baeafec4..ffb4b14c7e5 100644 --- a/tests/integration/translation/messages/bases/openai.py +++ b/tests/integration/translation/messages/bases/openai.py @@ -1,4 +1,5 @@ from typing import Final +from unittest.mock import ANY from integration.translation.case import TranslationTestCase from integration.translation.messages.templates import MESSAGES_BRIDGE_RESPONSE, MESSAGES_REQUEST @@ -100,6 +101,7 @@ GPT_5_4_TEST_CASE: Final = TranslationTestCase( ) + GPT_5_6_SOL_TEST_CASE: Final = TranslationTestCase( scenario="basic", litellm_endpoint="/v1/messages", @@ -784,3 +786,243 @@ GPT_5_6_TERRA_TEST_CASE: Final = TranslationTestCase( ], }, ) + + +GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE: Final = { + 'id': 'resp_0a3b11558c0819df006ae75c101de487d1812988a3147f6964', + 'object': 'response', + 'created_at': 1793547280, + 'status': 'completed', + 'access_programs': { + 'cyber': 'standard', + }, + 'background': False, + 'billing': { + 'payer': 'developer', + }, + 'completed_at': 1793547282, + 'error': None, + 'frequency_penalty': 0.0, + 'incomplete_details': None, + 'instructions': ( + 'You help maintain a synthetic Python project. Read the relevant files before suggesting ' + 'a fix. Explain which file you need next, then call a read-only tool. Never change files.' + ' Use the messages client for this project review. Consider zero, negative and non-intege' + 'r quantities before choosing the next file to inspect.' + ), + 'max_output_tokens': 1024, + 'max_tool_calls': None, + 'model': 'gpt-6.1-terra', + 'moderation': None, + 'output': [ + { + 'id': 'rs_0a3b11558c0819df006ae75c10fde087d192db4aa5ea7cf7be', + 'type': 'reasoning', + 'content': [], + 'encrypted_content': ( + 'gAAAAABq51wSSVCQB1815HYz5pLz1k32-dUjO-X-4b7LQG23OQZx_gqLXLuuL4xBCieTrvYatU55pFIxiQFXgtqG' + '6U1VtkToUospW-zTvH4roGicTQdWAovuoGt_w7rIFKNd0DUt8XB82WtVnogSd-ZQi4yJ3fjJLrR8nGTG596tQoGX' + '5TIFWeprIbpd99K1-bmu7dupFVg55x8zWfUx2e7wyYRFJ4JZLdIy1_2AwPaf5AjiZn5hnYXdGL3p7X_Bv_nkoRa4' + '1EE592bGS0K_GAxxVxH2sAdzQIOQf_G_E4fvnHRegGK61AgZQ9PVn2dXhGCXa-O0j1aYEx5pECMSfHaqExkx5-Nk' + 'z3l6Y7RmkoUKduquneXcZSRX-COeDTcts0hRFMTnlNQ5obc3tY_IEST-JDpKdsjL-6YEHhtJNrdED_DIj0vVrQgg' + '_3g0LfnDGSqtunsHs-KU4He_jYBJwXHNB2xbe5DMVAyNcqm7TOKRDejB_ym6cA_8j-oTXIumSnAao6I-l3WYU2yk' + 'tprvhby5FPnPhspqCYVu6nn5LxO7wyQOm_bOK4LcCojyp5OGRgCjtZ7AhAytPSryHt_gSMeEmQ11REFYh3PTrPt5' + 'ZqYYHW-miQ4Kgg80tn2I66EydrVEEaqZp8sQ7XgbFr7CG_6DOVGIGB819hLpA6clAZxNuUc8bVTwvT_o-wOLOePr' + 'Fa28kMGuucFWgLKW3fxQBh5MVHfMca-T8shc9aK8JLq7H74xfBaNWdXyNpMlNYr_kPC8LHqh2mKXMyG_17yShf-f' + 'h4MIY7dHrHr15X-aw8tAFBUZAkTTQF9Da4Cn09oX-yGGs1vW75HAPAdaBqVvAu_MAHXn_C3ACA4mKe7N4ihQWcVD' + 'zw9e0K6tKWwOYybCLenWnlJ64ooPajGtQvdUfYx4SGmcxTPd18q1_djz-J5k7T8gdqwiD5MEdJU3Trsrw7eULiFE' + 'qJu9oYrgsiVO-lsjIub5MPLCfKb8_L703ls2WBQ64BT-MZw2qgjKdHXk3f9KjRFaWM_HIJgaMrG6x9H2KE5Sqku9' + 'o1dANEH0ZpxyBb4lIofWnTrrXALN763TCQe0BC0IwmaoJBfAFThzhLbCuQBLsNZj4vi8rC7W6xSBxQ1UYCgSrZPh' + 'm8JUoGs4RWYgq7-mD3sB2jcRedcoG9RqxpF0h7_DIzHqk3UVnSpNiRnh_wGp4x_-lO2Ms6qp48QpSYOMJmG_KcRI' + '6qhcxTg2B3tU4965f2Iz0ghSzRiSctki1CPvWcRBtLv6LqLLoBK0NTgoByR66rUB7s6yYe6coP_OSkR0GFUCqH_X' + 'w-kcd-VckGJxKUm5tkejTjjrEXq3LiClTn9NUUgmtaWPEmZoHdNElyu1xiIK-0CTCb07zN_EK2_Nls5SRsWZBRFt' + '3YCGcw9vK2jSyx28cRwdBmb1fWXAQ3FYAl1uISH5kdcajQvWv1rhHPMW828OYZTZxG1whGwNPxOTWwj2sHuxvMwG' + 'MmOnhdTnIX-5qoNafrWraIv8jBC4Y4Z_hlCaB89Ba4Y_-B5-0ClNLGOx6q9fzj3wY4H3RAymTbi9pqqUpuX7wWBG' + 'uL9KggI6a5A09tmTIpucIsHY7dH6c12Xrls7vkrxlQh_7iix67VUj9UmspFvnCSVmX0W3IdPszNZpVHNpm_KOD-v' + 'Y5fSNhkTk_hTjjlSMhSe6Ki7BarnMzPo8j7EHVZcgmoAOMoNDHvIEPjbCSXphGr9qYfQ4ajffaloJLh-51e0C8mJ' + '1daJ2xs7ZT7uJI0syeeKVRnqxDYlvoAEKl1KrUrX9SKceoVANOla-DMWs3TSsUL6-ccPqzJFDdPn6aVoIxS4IMGa' + 'nn5oWXVRxLUS01d19mVPn_XoNXrLwi2GCW0r8GfowHyeEgW535xwNt5uEGmmmV17baclC6x1GUo3xPkKpnPaVgf7' + 'jIjBP7P8-FOcHoIFB9MfUL_Ot2UdK26tc7vL7CgUuch08WPZOklx8Vsv7N0OIzWiczrA09il52Z_QyyTB5VmfiYS' + 'X6cLsnFCTh7fTSDs4p80vEfBWqKCW3M0isAWLTEaQ7kwpmHulUI_fvxJg2Bn-lV48aKaLeZT0FAS_WRP-cGBIb79' + 's8TlmnRcyBJhR0LbMEyMHqo4Y7hwJAyTZkBtejuCyyE3b-2QKq2w-GtcgD5MI9b6EOt7ET6EbFFS' + ), + 'summary': [], + }, + { + 'id': 'msg_0a3b11558c0819df006ae75c11a3c087d18ee211f7533e565f', + 'type': 'message', + 'status': 'completed', + 'content': [ + { + 'type': 'output_text', + 'annotations': [], + 'logprobs': [], + 'text': ( + 'I’ll read `shop/validation.py` first, checking how it handles zero, negative, and non-in' + 'teger quantities.' + ), + }, + ], + 'phase': 'commentary', + 'role': 'assistant', + }, + { + 'id': 'fc_0a3b11558c0819df006ae75c12142887d18b71a86e0c02ae8c', + 'type': 'function_call', + 'status': 'completed', + 'arguments': '{"path":"shop/validation.py","start_line":1,"end_line":150}', + 'call_id': 'call_Fnk0hANehtgpqZaZieVoZUYK', + 'name': 'read_file', + }, + ], + 'parallel_tool_calls': True, + 'presence_penalty': 0.0, + 'previous_response_id': None, + 'prompt_cache_key': None, + 'prompt_cache_retention': '24h', + 'reasoning': { + 'context': 'all_turns', + 'effort': 'high', + 'mode': 'standard', + 'summary': None, + }, + 'safety_identifier': None, + 'service_tier': 'default', + 'store': True, + 'temperature': 1.0, + 'text': { + 'format': { + 'type': 'text', + }, + 'verbosity': 'medium', + }, + 'tool_choice': 'auto', + 'tool_usage': { + 'image_gen': { + 'input_tokens': 0, + 'input_tokens_details': { + 'image_tokens': 0, + 'text_tokens': 0, + }, + 'output_tokens': 0, + 'output_tokens_details': { + 'image_tokens': 0, + 'text_tokens': 0, + }, + 'total_tokens': 0, + }, + 'web_search': { + 'num_requests': 0, + }, + }, + 'tools': [ + { + 'type': 'function', + 'description': 'Search source and test files for a literal term.', + 'name': 'search_files', + 'output_schema': None, + 'parameters': { + 'type': 'object', + 'properties': { + 'query': { + 'type': 'string', + }, + 'paths': { + 'type': 'array', + 'items': { + 'type': 'string', + }, + }, + }, + 'required': [ + 'query', + 'paths', + ], + 'additionalProperties': False, + }, + 'strict': False, + }, + { + 'type': 'function', + 'description': 'Read a range of lines from a project file.', + 'name': 'read_file', + 'output_schema': None, + 'parameters': { + 'type': 'object', + 'properties': { + 'path': { + 'type': 'string', + }, + 'start_line': { + 'type': 'integer', + 'minimum': 1, + }, + 'end_line': { + 'type': 'integer', + 'minimum': 1, + }, + }, + 'required': [ + 'path', + 'start_line', + 'end_line', + ], + 'additionalProperties': False, + }, + 'strict': False, + }, + ], + 'top_logprobs': 0, + 'top_p': 0.98, + 'truncation': 'disabled', + 'usage': { + 'input_tokens': 309, + 'input_tokens_details': { + 'cache_write_tokens': 0, + 'cached_tokens': 0, + }, + 'output_tokens': 121, + 'output_tokens_details': { + 'reasoning_tokens': 56, + }, + 'total_tokens': 430, + }, + 'user': None, + 'metadata': {}, +} + +GPT_6_1_TERRA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/messages", + litellm_request={**MESSAGES_REQUEST, "model": "openai/gpt-6.1-terra"}, + expected_provider_endpoint="/responses", + expected_provider_headers=GPT_5_6_TERRA_TEST_CASE.expected_provider_headers, + expected_provider_request={ + **OPENAI_RESPONSES_REQUEST_FROM_MESSAGES, + "model": "gpt-6.1-terra", + }, + mock_provider_response=GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE, + expected_litellm_response={ + **GPT_5_6_TERRA_TEST_CASE.expected_litellm_response, + "id": ANY, + "content": [ + { + "type": "redacted_thinking", + "data": "litellm_encrypted_reasoning:" + + GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE["output"][0]["encrypted_content"], + }, + { + "type": "text", + "text": "I’ll read `shop/validation.py` first, checking how it handles zero, negative, and non-integer quantities.", + }, + { + "type": "tool_use", + "id": "call_Fnk0hANehtgpqZaZieVoZUYK", + "name": "read_file", + "input": {"path": "shop/validation.py", "start_line": 1, "end_line": 150}, + }, + ], + "usage": {"input_tokens": 309, "output_tokens": 121}, + "model": "openai/gpt-6.1-terra", + }, +) diff --git a/tests/integration/translation/messages/basic/test_messages_basic_openai.py b/tests/integration/translation/messages/basic/test_messages_basic_openai.py index 38d864411c0..fc9b8b25a56 100644 --- a/tests/integration/translation/messages/basic/test_messages_basic_openai.py +++ b/tests/integration/translation/messages/basic/test_messages_basic_openai.py @@ -7,6 +7,7 @@ from integration.translation.messages.bases.openai import ( GPT_5_6_LUNA_TEST_CASE, GPT_5_6_SOL_TEST_CASE, GPT_5_6_TERRA_TEST_CASE, + GPT_6_1_TERRA_TEST_CASE, GPT_6_1_SOL_TEST_CASE, GPT_6_ASTRA_TEST_CASE, GPT_6_LUNA_TEST_CASE, @@ -24,6 +25,7 @@ from integration.translation.runner import assert_translation GPT_6_1_SOL_TEST_CASE, GPT_6_ASTRA_TEST_CASE, GPT_5_6_TERRA_TEST_CASE, + GPT_6_1_TERRA_TEST_CASE, ], ids=lambda case: case.id, ) diff --git a/tests/integration/translation/responses/bases/openai.py b/tests/integration/translation/responses/bases/openai.py index 8e379e1019f..7a6515bc2d3 100644 --- a/tests/integration/translation/responses/bases/openai.py +++ b/tests/integration/translation/responses/bases/openai.py @@ -161,6 +161,7 @@ GPT_5_4_TEST_CASE: Final = TranslationTestCase( ) + GPT_5_6_SOL_TEST_CASE: Final = TranslationTestCase( scenario="basic", litellm_endpoint="/v1/responses", @@ -1158,3 +1159,256 @@ GPT_5_6_TERRA_TEST_CASE: Final = TranslationTestCase( "top_logprobs": 0, }, ) + + +GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE: Final = { + 'id': 'resp_0489dbceb3070b9a006ae75c12ef5487d1a7cb64a92d8774d1', + 'object': 'response', + 'created_at': 1793547282, + 'status': 'completed', + 'access_programs': { + 'cyber': 'standard', + }, + 'background': False, + 'billing': { + 'payer': 'developer', + }, + 'completed_at': 1793547285, + 'error': None, + 'frequency_penalty': 0.0, + 'incomplete_details': None, + 'instructions': ( + 'You help maintain a synthetic Python project. Read the relevant files before suggesting ' + 'a fix. Explain which file you need next, then call a read-only tool. Never change files.' + ' Use the responses client for this project review. Consider zero, negative and non-integ' + 'er quantities before choosing the next file to inspect.' + ), + 'max_output_tokens': 1024, + 'max_tool_calls': None, + 'model': 'gpt-6.1-terra', + 'moderation': None, + 'output': [ + { + 'id': 'rs_0489dbceb3070b9a006ae75c13f80487d1ab5a5153f0461603', + 'type': 'reasoning', + 'content': [], + 'encrypted_content': ( + 'gAAAAABq51wVlJWN-LTJqqhWvFyWjY49-yFum5T56W8eITsd-qT0V290Gw80RoL9VVX4jvv6cfpCOb73lk6WHbMW' + 'q0tjO3yeVbczh_0YDEhG4-CGvQaElquYG1AK2fABB3X_J3xPglgIB9OnPuQiLoYBQHqYy3U-0TinuAr0lFCcWFex' + 'r1JAcM5JExGND9kJUCXx6Zfpt1_e4M467kCKmYW_pZ3Y0Ndf5uFLooX18Xf9-GBGiB6TtaS_atSGAVaeBYFYaNc4' + 'WIaTG-675Lnd6dHGQIrV4jBW7Xf4QKlQU1hFZCkUg0JW54skR8c7iMdA8qvdo2ieZ6JgnxU0gujk3OycBhXM1SaL' + 'P-MenI0QsOFcWASEozr-U53h-b4Gek9TBwY1PGMA8hITFw7tEwpt-s9LvZuDr0kcknR5d8RYyf1owYV-O668ykR5' + 'VUzheo2NOVUzQIe9xQorENDnxrdya8gO54HxDV9ShzbZ9e9ymv9iRH6jCjSaTOXJdCPjfxd5aYoPTnfibh0RYxM2' + 'UlcMZhpv5aXfu7c7hUbXFKx1eky48LAE0s1DjcVGa0YCqFNWAJEYJR7ZHpcaN8dzAc4HwNZZo2Oh15AfybRkm8Zh' + 'Jb5EalmOETrLK0_jxlH29Ln4xqpwlBHWeq6l0z_Qt3CqihV4dV5gsRGaJky6NoSn7UjpWaCzAkFjf1R4nIvqsJDM' + 'CmFAlS32ne_nL9spLd3uUAXzMCLwnfCs30xp8XxDwFwYq7LweRjdBkEBeOibTsaACR_b4Cp5GwICWsqrzXRpSh7K' + 'w73iewX7dq6gOiXZlf3bFg6A35h2EIVUPwBnEViN-mwgebe1pLH3vFUHocR3K70PIs7qLlWE5-ZsX_qVd_E1EmbR' + 'zom8leGZ798zodGpJyy-aTI49RgsPwk4gWugaoB8MKI3ykkmAeLbF3pDRvzTg3ZxF49fFS-0ALrQhB2177MZWymu' + 'ZHh_SQFi12KCMhzXxO8GkzeMDFV0OKezVkeveafa1eRfWReJJqaobBWd705vLaqidOTIYErHGVhEDKL9judPl0nl' + 'UhPXh4lDw7LN1qVXUiTFateiic7m-y-ibeTJj500tooNOJG4BSlmHYgZF1hA1FUEtQlDWXFbTTcz8yTXLB0ucbXb' + 'GudNKyI6u2oTPn0kaZvHuw5tra6_Lkp2G1DJ9ZL-tMLRLH8Fca4RzVTJnoqHZ2S-rl7ukKcYKQaar5ZE4I2zL_F7' + 'n_4Zr6lIlKOapXkcvso5UpThSy6OnMcUVh9DqWBKcCcQRA3TSshiQHNuY8xQIoNdm7YL4pRzufuvykbINnfUS0UD' + 'RUOSgNGImQHwNggEJysPx9ctqRXW0hpvcF5wrZbAtGLa6Eun-mBQ_z6-b7vT_uIJmzD9PWoaMfcHEb5fa4nXVFsx' + 'xBIvlMZ8cM7Yims2aG9PT1V7UrsUyVPP_K8fHJdheOM4oy4nC77fYrEjSUJeh-uCJ6wbXE0PuNBQWivWcwE9VV7U' + 'jXiIsCEblEVGHlhKL2EEajfB0tEYDOTVV4B2agwwLU5S6JX91UCpcH1dvFTYS_roXMDf3CWmo0JseRW2oZzxcCoP' + 'NZVvGEMhTCsitwVUEaRBPfNtLiplhbOrUx80IY38kRld9OQb6KxOvyuxqG4LT4_afTQImSGEZJQSW8qo9GzKN_sJ' + '9iQvGw6tgqrwqmmLKXjFDp3I5FB29xZAOoxhnapGIKL6KUuehubY_kM5ok21PvPuvfsY-gaFzFQB5dJsaBNZoDaJ' + '4cB1pw-tXmP4gUECk0PkoMQEekSzBJLfwk7jbIMS_YSzpE1RcqFenprMVkq-HBfAaaKIQxRi2qB3WM2VaoYGDDFG' + 'Xi3E3lc6x0D64-vXtxo4EPK-eXPC-ThPShl6POgKuoQZjDvo918hJDn3PCBq7jVXeEAgpOvLkSWQnen_khH5y4Un' + 'tF8L1auZfD2YugvETRdQsQKuX5ZCJ0_gT9L2Olc3QXbZoE4wzUBiyBdLlysDZanR4e3bgff3ZcsH02Et9iO2ljbO' + '8ELqlEzfZWV6lU_MT8GtHJfeIzDPp4UDraHdwyQYtkbJ9LNaub0JR4sushyYO6fLZLB45GqP8TJtCVlorF6okoy4' + 'AAqBvLb9vu2PAD8a9pjfZ6WNypYJelZ9eEsBTQ_sZGWnBFmvNhjZbFoXHkNAgp9HL0msO7ydRPnL_BPytOMXHiqy' + '5VcVaLnRCno3wm-QftrJyrp8AQKnjZL8DEXAYUUrAGofQ5wFA7HhjKGPTTLxd-cahYh9Lkkfwp3fUj3YgPTYDM35' + 'I4dpgUG9UCutIYwtmgdM-uKiot2w' + ), + 'summary': [], + }, + { + 'id': 'msg_0489dbceb3070b9a006ae75c14b9d487d183c51260c69dd557', + 'type': 'message', + 'status': 'completed', + 'content': [ + { + 'type': 'output_text', + 'annotations': [], + 'logprobs': [], + 'text': ( + 'I’ll read `shop/validation.py` first to check how it handles zero, negative, and non-int' + 'eger quantities.' + ), + }, + ], + 'phase': 'commentary', + 'role': 'assistant', + }, + { + 'id': 'fc_0489dbceb3070b9a006ae75c152c9887d19f48a7ea1647f1e4', + 'type': 'function_call', + 'status': 'completed', + 'arguments': '{"path":"shop/validation.py","start_line":1,"end_line":200}', + 'call_id': 'call_J39X3VwRp2iE5zJYYELJRTOn', + 'name': 'read_file', + }, + ], + 'parallel_tool_calls': True, + 'presence_penalty': 0.0, + 'previous_response_id': None, + 'prompt_cache_key': None, + 'prompt_cache_retention': '24h', + 'reasoning': { + 'context': 'all_turns', + 'effort': 'high', + 'mode': 'standard', + 'summary': None, + }, + 'safety_identifier': None, + 'service_tier': 'default', + 'store': True, + 'temperature': 1.0, + 'text': { + 'format': { + 'type': 'text', + }, + 'verbosity': 'medium', + }, + 'tool_choice': 'auto', + 'tool_usage': { + 'image_gen': { + 'input_tokens': 0, + 'input_tokens_details': { + 'image_tokens': 0, + 'text_tokens': 0, + }, + 'output_tokens': 0, + 'output_tokens_details': { + 'image_tokens': 0, + 'text_tokens': 0, + }, + 'total_tokens': 0, + }, + 'web_search': { + 'num_requests': 0, + }, + }, + 'tools': [ + { + 'type': 'function', + 'description': 'Search source and test files for a literal term.', + 'name': 'search_files', + 'output_schema': None, + 'parameters': { + 'type': 'object', + 'properties': { + 'query': { + 'type': 'string', + }, + 'paths': { + 'type': 'array', + 'items': { + 'type': 'string', + }, + }, + }, + 'required': [ + 'query', + 'paths', + ], + 'additionalProperties': False, + }, + 'strict': True, + }, + { + 'type': 'function', + 'description': 'Read a range of lines from a project file.', + 'name': 'read_file', + 'output_schema': None, + 'parameters': { + 'type': 'object', + 'properties': { + 'path': { + 'type': 'string', + }, + 'start_line': { + 'type': 'integer', + 'minimum': 1, + }, + 'end_line': { + 'type': 'integer', + 'minimum': 1, + }, + }, + 'required': [ + 'path', + 'start_line', + 'end_line', + ], + 'additionalProperties': False, + }, + 'strict': True, + }, + ], + 'top_logprobs': 0, + 'top_p': 0.98, + 'truncation': 'disabled', + 'usage': { + 'input_tokens': 309, + 'input_tokens_details': { + 'cache_write_tokens': 0, + 'cached_tokens': 0, + }, + 'output_tokens': 131, + 'output_tokens_details': { + 'reasoning_tokens': 66, + }, + 'total_tokens': 440, + }, + 'user': None, + 'metadata': {}, +} + +GPT_6_1_TERRA_TEST_CASE: Final = TranslationTestCase( + scenario="basic", + litellm_endpoint="/v1/responses", + litellm_request={**RESPONSES_REQUEST, "model": "openai/gpt-6.1-terra"}, + expected_provider_endpoint="/responses", + expected_provider_headers=GPT_5_6_TERRA_TEST_CASE.expected_provider_headers, + expected_provider_request={ + **OPENAI_RESPONSES_REQUEST, + "model": "gpt-6.1-terra", + }, + mock_provider_response=GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE, + expected_litellm_response={ + **GPT_5_6_TERRA_TEST_CASE.expected_litellm_response, + "created_at": 1793547282, + "completed_at": 1793547285, + "model": "openai/gpt-6.1-terra", + "access_programs": {"cyber": "standard"}, + "output": [ + *GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE["output"][:2], + { + **GPT_6_1_TERRA_MOCK_PROVIDER_RESPONSE["output"][2], + "namespace": None, + }, + ], + "usage": { + "input_tokens": 309, + "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": 131, + "output_tokens_details": { + "audio_tokens": None, + "reasoning_tokens": 66, + "text_tokens": None, + }, + "total_tokens": 440, + "cost": None, + }, + }, +) diff --git a/tests/integration/translation/responses/basic/test_responses_basic_openai.py b/tests/integration/translation/responses/basic/test_responses_basic_openai.py index 0d5e46237d2..38b80e74eb2 100644 --- a/tests/integration/translation/responses/basic/test_responses_basic_openai.py +++ b/tests/integration/translation/responses/basic/test_responses_basic_openai.py @@ -7,6 +7,7 @@ from integration.translation.responses.bases.openai import ( GPT_5_6_LUNA_TEST_CASE, GPT_5_6_SOL_TEST_CASE, GPT_5_6_TERRA_TEST_CASE, + GPT_6_1_TERRA_TEST_CASE, GPT_6_1_SOL_TEST_CASE, GPT_6_ASTRA_TEST_CASE, GPT_6_LUNA_TEST_CASE, @@ -24,6 +25,7 @@ from integration.translation.runner import assert_translation GPT_6_1_SOL_TEST_CASE, GPT_6_ASTRA_TEST_CASE, GPT_5_6_TERRA_TEST_CASE, + GPT_6_1_TERRA_TEST_CASE, ], ids=lambda case: case.id, )