test(cost): add tier 1 cost tracking cases for gpt-5.6-terra, gemini-4-argon and gemini-3.1-pro-preview (#46931)

* test(cost): add tier 1 cost tracking cases for gpt-5.6-terra, gemini-4-argon and gemini-3.1-pro-preview

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cost): add audit 3 shape cases for vertex_ai and azure_ai claude

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cost): mark azure gpt-5.6-terra priority case as known bug

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
devin-ai-integration[bot] 2026-10-16 10:31:41 -07:00 • committed by GitHub
parent 7ddc9f1c96
commit ee4860dd84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 1180 additions and 7 deletions

View file

@ -4111,6 +4111,7 @@ CLAUDE_OPUS_5_5_INPUT_TEXT: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
},
),
@ -4170,6 +4171,7 @@ CLAUDE_SONNET_5_5_INPUT_TEXT: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -4232,6 +4234,7 @@ CLAUDE_SONNET_5_5_STREAM: Final = CostTrackingTestCase(
"output_tokens": 1,
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -4314,6 +4317,7 @@ CLAUDE_SONNET_5_5_CACHE_READ: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -4566,6 +4570,7 @@ CLAUDE_HAIKU_5_5_INPUT_TEXT: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -4628,6 +4633,7 @@ CLAUDE_HAIKU_5_5_STREAM: Final = CostTrackingTestCase(
"output_tokens": 1,
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -4710,6 +4716,7 @@ CLAUDE_HAIKU_5_5_CACHE_READ: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -5325,6 +5332,7 @@ CLAUDE_FABLE_5_1_INPUT_TEXT: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -5387,6 +5395,7 @@ CLAUDE_FABLE_5_1_STREAM: Final = CostTrackingTestCase(
"output_tokens": 1,
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -5469,6 +5478,7 @@ CLAUDE_FABLE_5_1_CACHE_READ: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -5720,6 +5730,7 @@ CLAUDE_OPUS_5_5_STREAM: Final = CostTrackingTestCase(
"output_tokens": 1,
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -5802,6 +5813,7 @@ CLAUDE_OPUS_5_5_CACHE_READ: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -6141,6 +6153,7 @@ CLAUDE_SONNET_5_5_THINKING: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -6294,6 +6307,7 @@ CLAUDE_HAIKU_5_5_THINKING: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 3480},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -6593,6 +6607,7 @@ CLAUDE_FABLE_5_1_THINKING: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -6746,6 +6761,7 @@ CLAUDE_OPUS_5_5_THINKING: Final = CostTrackingTestCase(
"output_tokens_details": {"thinking_tokens": 3480},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},

View file

@ -2,7 +2,7 @@
PARITY pairs the streamed case with its plain twin where both bill the same row."""
from typing import Final
from typing import Final, cast
from integration.cost_calculation.cost_tracking_case import (
with_response_usage,
@ -23,6 +23,20 @@ from integration.cost_calculation.bridge_cost_parity.case import BridgeCostParit
from integration.cost_calculation.stream_parity.case import StreamParityTestCase, sse_frames
def _response_for_model(response: JsonResponse, model: str) -> JsonResponse:
return response.model_copy(update={"body": {**response.body, "model": model}})
def _stream_for_model(response: SseResponse, model: str) -> SseResponse:
return response.model_copy(
update={
"frames": tuple(
frame.replace("gpt-6-luna-2026-09-22", model).replace("gpt-6-luna", model) for frame in response.frames
)
}
)
# azure/gpt-5.4-mini
AZURE_GPT_5_4_MINI_INPUT_TEXT: Final = CostTrackingTestCase(
name="azure-gpt-5.4-mini-input_text",
@ -6174,6 +6188,152 @@ AZURE_GPT_6_LUNA_CACHE_WRITE_5M: Final = with_response_usage(
"content_filter_result": {"error": {"code": "content_filter_error", "message": "The contents are not filtered"}}
},
)
AZURE_GPT_5_6_TERRA_INPUT_TEXT: Final = AZURE_GPT_6_LUNA_INPUT_TEXT.model_copy(
update={
"name": "azure-gpt-5.6-terra-input_text",
"model": "azure/gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, AZURE_GPT_6_LUNA_INPUT_TEXT.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.0094864,
input_cost=0.004048,
output_cost=0.0054384,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
AZURE_GPT_5_6_TERRA_STREAM: Final = AZURE_GPT_6_LUNA_STREAM.model_copy(
update={
"name": "azure-gpt-5.6-terra-stream",
"model": "azure/gpt-5.6-terra",
"response": _stream_for_model(
cast(SseResponse, AZURE_GPT_6_LUNA_STREAM.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.0094864,
input_cost=0.004048,
output_cost=0.0054384,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
AZURE_GPT_5_6_TERRA_SERVICE_TIER_FLEX: Final = AZURE_GPT_6_LUNA_SERVICE_TIER_FLEX.model_copy(
update={
"name": "azure-gpt-5.6-terra-service_tier_flex",
"model": "azure/gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, AZURE_GPT_6_LUNA_SERVICE_TIER_FLEX.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.0047432,
input_cost=0.002024,
output_cost=0.0027192,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
AZURE_GPT_5_6_TERRA_SERVICE_TIER_PRIORITY: Final = AZURE_GPT_6_LUNA_SERVICE_TIER_PRIORITY.model_copy(
update={
"name": "azure-gpt-5.6-terra-service_tier_priority",
"model": "azure/gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, AZURE_GPT_6_LUNA_SERVICE_TIER_PRIORITY.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.0189728,
input_cost=0.008096,
output_cost=0.0108768,
prompt_tokens=1840,
completion_tokens=412,
),
"known_bug": "Azure GPT Terra priority service tier is billed at the base rate",
}
)
AZURE_GPT_5_6_TERRA_MESSAGES_BRIDGED_JSON: Final = AZURE_GPT_6_LUNA_MESSAGES_BRIDGED_JSON.model_copy(
update={
"name": "azure-gpt-5.6-terra-messages_bridged_json",
"model": "azure/gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, AZURE_GPT_6_LUNA_MESSAGES_BRIDGED_JSON.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.0094864,
input_cost=0.004048,
output_cost=0.0054384,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
AZURE_GPT_5_6_TERRA_CACHE_READ: Final = AZURE_GPT_6_LUNA_CACHE_READ.model_copy(
update={
"name": "azure/gpt-5.6-terra-cache_read",
"model": "azure/gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, AZURE_GPT_6_LUNA_CACHE_READ.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.00912736,
input_cost=0.00411136,
output_cost=0.005016,
prompt_tokens=12928,
completion_tokens=380,
),
}
)
AZURE_GPT_5_6_TERRA_CACHE_WRITE_5M: Final = AZURE_GPT_6_LUNA_CACHE_WRITE_5M.model_copy(
update={
"name": "azure/gpt-5.6-terra-cache_write_5m",
"model": "azure/gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, AZURE_GPT_6_LUNA_CACHE_WRITE_5M.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.040216,
input_cost=0.0352,
output_cost=0.005016,
prompt_tokens=12928,
completion_tokens=380,
),
}
)
AZURE_GPT_5_6_TERRA_REASONING: Final = AZURE_GPT_6_LUNA_REASONING.model_copy(
update={
"name": "azure/gpt-5.6-terra-reasoning",
"model": "azure/gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, AZURE_GPT_6_LUNA_REASONING.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.056056,
input_cost=0.002728,
output_cost=0.053328,
prompt_tokens=1240,
completion_tokens=4040,
),
}
)
AZURE_GPT_5_6_TERRA_TOOL_CALL: Final = AZURE_GPT_6_LUNA_TOOL_CALL.model_copy(
update={
"name": "azure/gpt-5.6-terra-tool_call",
"model": "azure/gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, AZURE_GPT_6_LUNA_TOOL_CALL.response), "gpt-5.6-terra-2026-07-09"
),
"expected": ExactExpected(
spend=0.0094864,
input_cost=0.004048,
output_cost=0.0054384,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
AZURE_GPT_6_ASTRA_CACHE_WRITE_5M: Final = with_response_usage(
AZURE_GPT_6_ASTRA_CACHE_READ,
"azure/gpt-6-astra-cache_write_5m",
@ -6304,6 +6464,15 @@ CASES: Final[tuple[CostTrackingTestCase, ...]] = (
AZURE_GPT_6_1_SOL_CACHE_WRITE_5M,
AZURE_GPT_6_LUNA_CACHE_WRITE_5M,
AZURE_GPT_6_ASTRA_CACHE_WRITE_5M,
AZURE_GPT_5_6_TERRA_INPUT_TEXT,
AZURE_GPT_5_6_TERRA_STREAM,
AZURE_GPT_5_6_TERRA_SERVICE_TIER_FLEX,
AZURE_GPT_5_6_TERRA_SERVICE_TIER_PRIORITY,
AZURE_GPT_5_6_TERRA_MESSAGES_BRIDGED_JSON,
AZURE_GPT_5_6_TERRA_CACHE_READ,
AZURE_GPT_5_6_TERRA_CACHE_WRITE_5M,
AZURE_GPT_5_6_TERRA_REASONING,
AZURE_GPT_5_6_TERRA_TOOL_CALL,
)
PARITY: Final[tuple[StreamParityTestCase, ...]] = (
@ -6316,6 +6485,7 @@ PARITY: Final[tuple[StreamParityTestCase, ...]] = (
StreamParityTestCase(plain=AZURE_GPT_6_LUNA_INPUT_TEXT, streamed=AZURE_GPT_6_LUNA_STREAM),
StreamParityTestCase(plain=AZURE_GPT_6_ASTRA_INPUT_TEXT, streamed=AZURE_GPT_6_ASTRA_STREAM),
StreamParityTestCase(plain=AZURE_GPT_6_1_SOL_INPUT_TEXT, streamed=AZURE_GPT_6_1_SOL_STREAM),
StreamParityTestCase(plain=AZURE_GPT_5_6_TERRA_INPUT_TEXT, streamed=AZURE_GPT_5_6_TERRA_STREAM),
)
BRIDGE_COST_PARITY: Final[tuple[BridgeCostParityTestCase, ...]] = (
@ -6327,4 +6497,7 @@ BRIDGE_COST_PARITY: Final[tuple[BridgeCostParityTestCase, ...]] = (
BridgeCostParityTestCase(native=AZURE_GPT_6_LUNA_INPUT_TEXT, bridged=AZURE_GPT_6_LUNA_MESSAGES_BRIDGED_JSON),
BridgeCostParityTestCase(native=AZURE_GPT_6_ASTRA_INPUT_TEXT, bridged=AZURE_GPT_6_ASTRA_MESSAGES_BRIDGED_JSON),
BridgeCostParityTestCase(native=AZURE_GPT_6_1_SOL_INPUT_TEXT, bridged=AZURE_GPT_6_1_SOL_MESSAGES_BRIDGED_JSON),
BridgeCostParityTestCase(
native=AZURE_GPT_5_6_TERRA_INPUT_TEXT, bridged=AZURE_GPT_5_6_TERRA_MESSAGES_BRIDGED_JSON
),
)

View file

@ -2,7 +2,7 @@
PARITY pairs the streamed case with its plain twin where both bill the same row."""
from typing import Final
from typing import Final, cast
from integration.cost_calculation.bridge_cost_parity.case import BridgeCostParityTestCase, bridge_pairs
from integration.cost_calculation.cost_tracking_case import (
@ -16,6 +16,32 @@ from integration.cost_calculation.cost_tracking_case import (
)
from integration.cost_calculation.stream_parity.case import StreamParityTestCase, sse_frames
def _gemini_case_response(response: JsonResponse | SseResponse, model_version: str) -> JsonResponse | SseResponse:
match response:
case JsonResponse():
return response.model_copy(update={"body": {**response.body, "modelVersion": model_version}})
case SseResponse():
return response.model_copy(
update={
"frames": tuple(frame.replace("gemini-3.8-flash", model_version) for frame in response.frames)
}
)
def _gemini_case(
sibling: CostTrackingTestCase, name: str, model: str, model_version: str, expected: ExactExpected
) -> CostTrackingTestCase:
return sibling.model_copy(
update={
"name": name,
"model": model,
"response": _gemini_case_response(cast(JsonResponse | SseResponse, sibling.response), model_version),
"expected": expected,
}
)
# gemini/gemini-3.1-pro
GEMINI_GEMINI_3_1_PRO_INPUT_TEXT: Final = CostTrackingTestCase(
name="gemini-gemini-3.1-pro-input_text",
@ -3543,6 +3569,51 @@ GEMINI_GEMINI_3_1_PRO_CACHE_CREATION: Final = CostTrackingTestCase(
),
)
GEMINI_GEMINI_4_ARGON_INPUT_TEXT: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_INPUT_TEXT, "gemini-gemini-4-argon-input_text", "gemini/gemini-4-argon",
"gemini-4-argon", ExactExpected(spend=0.00858, input_cost=0.004048, output_cost=0.004532, prompt_tokens=1840, completion_tokens=412)
)
GEMINI_GEMINI_4_ARGON_STREAM: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_STREAM, "gemini-gemini-4-argon-stream", "gemini/gemini-4-argon",
"gemini-4-argon", ExactExpected(spend=0.00858, input_cost=0.004048, output_cost=0.004532, prompt_tokens=1840, completion_tokens=412)
)
GEMINI_GEMINI_4_ARGON_CACHE_READ: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_CACHE_READ, "gemini-gemini-4-argon-cache_read", "gemini/gemini-4-argon",
"gemini-4-argon", ExactExpected(spend=0.00693968, input_cost=0.00275968, output_cost=0.00418, prompt_tokens=12928, completion_tokens=380)
)
GEMINI_GEMINI_4_ARGON_REASONING: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_REASONING, "gemini-gemini-4-argon-reasoning", "gemini/gemini-4-argon",
"gemini-4-argon", ExactExpected(spend=0.047168, input_cost=0.002728, output_cost=0.04444, prompt_tokens=1240, completion_tokens=4040)
)
GEMINI_GEMINI_4_ARGON_TOOL_CALL: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_TOOL_CALL, "gemini-gemini-4-argon-tool_call", "gemini/gemini-4-argon",
"gemini-4-argon", ExactExpected(spend=0.00858, input_cost=0.004048, output_cost=0.004532, prompt_tokens=1840, completion_tokens=412)
)
GEMINI_GEMINI_3_1_PRO_PREVIEW_INPUT_TEXT: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_INPUT_TEXT, "gemini-gemini-3.1-pro-preview-input_text",
"gemini/gemini-3.1-pro-preview", "gemini-3.1-pro-preview",
ExactExpected(spend=0.0112112, input_cost=0.004784, output_cost=0.0064272, prompt_tokens=1840, completion_tokens=412)
)
GEMINI_GEMINI_3_1_PRO_PREVIEW_STREAM: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_STREAM, "gemini-gemini-3.1-pro-preview-stream",
"gemini/gemini-3.1-pro-preview", "gemini-3.1-pro-preview",
ExactExpected(spend=0.0112112, input_cost=0.004784, output_cost=0.0064272, prompt_tokens=1840, completion_tokens=412)
)
GEMINI_GEMINI_3_1_PRO_PREVIEW_CACHE_READ: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_CACHE_READ, "gemini-gemini-3.1-pro-preview-cache_read",
"gemini/gemini-3.1-pro-preview", "gemini-3.1-pro-preview",
ExactExpected(spend=0.01078688, input_cost=0.00485888, output_cost=0.005928, prompt_tokens=12928, completion_tokens=380)
)
GEMINI_GEMINI_3_1_PRO_PREVIEW_REASONING: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_REASONING, "gemini-gemini-3.1-pro-preview-reasoning",
"gemini/gemini-3.1-pro-preview", "gemini-3.1-pro-preview",
ExactExpected(spend=0.066248, input_cost=0.003224, output_cost=0.063024, prompt_tokens=1240, completion_tokens=4040)
)
GEMINI_GEMINI_3_1_PRO_PREVIEW_TOOL_CALL: Final = _gemini_case(
GEMINI_GEMINI_3_8_FLASH_TOOL_CALL, "gemini-gemini-3.1-pro-preview-tool_call",
"gemini/gemini-3.1-pro-preview", "gemini-3.1-pro-preview",
ExactExpected(spend=0.0112112, input_cost=0.004784, output_cost=0.0064272, prompt_tokens=1840, completion_tokens=412)
)
CASES: Final[tuple[CostTrackingTestCase, ...]] = (
GEMINI_GEMINI_3_1_PRO_INPUT_TEXT,
@ -3605,6 +3676,16 @@ CASES: Final[tuple[CostTrackingTestCase, ...]] = (
GEMINI_NANO_BANANA_2_1_WEB_SEARCH_SINGLE_QUERY,
GEMINI_NANO_BANANA_2_1_WEB_SEARCH_MULTIPLE_QUERIES,
GEMINI_GEMINI_3_1_PRO_CACHE_CREATION,
GEMINI_GEMINI_4_ARGON_INPUT_TEXT,
GEMINI_GEMINI_4_ARGON_STREAM,
GEMINI_GEMINI_4_ARGON_CACHE_READ,
GEMINI_GEMINI_4_ARGON_REASONING,
GEMINI_GEMINI_4_ARGON_TOOL_CALL,
GEMINI_GEMINI_3_1_PRO_PREVIEW_INPUT_TEXT,
GEMINI_GEMINI_3_1_PRO_PREVIEW_STREAM,
GEMINI_GEMINI_3_1_PRO_PREVIEW_CACHE_READ,
GEMINI_GEMINI_3_1_PRO_PREVIEW_REASONING,
GEMINI_GEMINI_3_1_PRO_PREVIEW_TOOL_CALL,
)
PARITY: Final[tuple[StreamParityTestCase, ...]] = (
@ -3626,6 +3707,10 @@ PARITY: Final[tuple[StreamParityTestCase, ...]] = (
streamed=GEMINI_GEMINI_3_8_FLASH_STREAM_RESPONSE_MODEL_OVERRIDE,
),
StreamParityTestCase(plain=GEMINI_GEMINI_3_8_FLASH_TOOL_CALL, streamed=GEMINI_GEMINI_3_8_FLASH_STREAM_TOOL_CALL),
StreamParityTestCase(plain=GEMINI_GEMINI_4_ARGON_INPUT_TEXT, streamed=GEMINI_GEMINI_4_ARGON_STREAM),
StreamParityTestCase(
plain=GEMINI_GEMINI_3_1_PRO_PREVIEW_INPUT_TEXT, streamed=GEMINI_GEMINI_3_1_PRO_PREVIEW_STREAM
),
)
BRIDGE_COST_PARITY: Final[tuple[BridgeCostParityTestCase, ...]] = (
@ -3638,4 +3723,6 @@ BRIDGE_COST_PARITY: Final[tuple[BridgeCostParityTestCase, ...]] = (
),
("/v1/responses", "/v1/messages"),
),
*bridge_pairs((GEMINI_GEMINI_4_ARGON_INPUT_TEXT,), ("/v1/responses",)),
*bridge_pairs((GEMINI_GEMINI_3_1_PRO_PREVIEW_INPUT_TEXT,), ("/v1/responses",)),
)

View file

@ -2,7 +2,9 @@
PARITY pairs the streamed case with its plain twin where both bill the same row."""
from typing import Final
from typing import Final, cast
from pydantic import JsonValue
from integration.cost_calculation.cost_tracking_case import (
ALWAYS_OPEN_OFF_PEAK_WINDOW,
@ -20,13 +22,91 @@ from integration.cost_calculation.cost_tracking_case import (
)
from integration.cost_calculation.stream_parity.case import StreamParityTestCase, sse_frames
from integration.cost_calculation.cases.anthropic import (
CLAUDE_FABLE_5_1_CACHE_READ,
CLAUDE_FABLE_5_1_CACHE_WRITE_1H,
CLAUDE_FABLE_5_1_CACHE_WRITE_5M,
CLAUDE_FABLE_5_1_INPUT_TEXT,
CLAUDE_FABLE_5_1_STREAM,
CLAUDE_FABLE_5_1_THINKING,
CLAUDE_FABLE_5_1_TOOL_CALL,
CLAUDE_HAIKU_5_5_CACHE_READ,
CLAUDE_HAIKU_5_5_CACHE_WRITE_1H,
CLAUDE_HAIKU_5_5_CACHE_WRITE_5M,
CLAUDE_HAIKU_5_5_INPUT_TEXT,
CLAUDE_HAIKU_5_5_STREAM,
CLAUDE_HAIKU_5_5_THINKING,
CLAUDE_HAIKU_5_5_TOOL_CALL,
)
def _azure_ai_claude_usage(
input_tokens: int,
output_tokens: int,
inference_geo: str,
*,
cache_creation_input_tokens: int = 0,
cache_read_input_tokens: int = 0,
ephemeral_5m_input_tokens: int = 0,
ephemeral_1h_input_tokens: int = 0,
thinking_tokens: int = 0,
) -> dict[str, JsonValue]:
return {
"input_tokens": input_tokens,
"cache_creation_input_tokens": cache_creation_input_tokens,
"cache_read_input_tokens": cache_read_input_tokens,
"cache_creation": {
"ephemeral_5m_input_tokens": ephemeral_5m_input_tokens,
"ephemeral_1h_input_tokens": ephemeral_1h_input_tokens,
},
"output_tokens": output_tokens,
"output_tokens_details": {"thinking_tokens": thinking_tokens},
"service_tier": "standard",
"inference_geo": inference_geo,
"speed": "standard",
}
def _azure_ai_claude_shape_case(
sibling: CostTrackingTestCase,
name: str,
model: str,
usage: dict[str, JsonValue],
expected: ExactExpected,
response_content: list[dict[str, JsonValue]] | None = None,
adaptive_thinking: bool = False,
) -> CostTrackingTestCase:
response: Final = cast(JsonResponse, sibling.response)
request: Final = (
{
**{
key: value
for key, value in sibling.request.items()
if key not in {"reasoning_effort", "allowed_openai_params"}
},
"thinking": {"type": "adaptive"},
"output_config": {"effort": "medium"},
"allowed_openai_params": ["thinking", "output_config"],
}
if adaptive_thinking
else sibling.request
)
body: Final = {
**response.body,
"model": model.rsplit("/", 1)[-1],
"usage": usage,
**({"content": response_content} if response_content is not None else {}),
}
return sibling.model_copy(
update={
"name": name,
"model": model,
"request": request,
"response": response.model_copy(update={"body": body}),
"expected": expected,
}
)
# nova-next
NOVA_NEXT_TRANSCRIPTIONS_PER_SECOND: Final = CostTrackingTestCase(
name="nova-next-transcriptions-per-second",
@ -1457,6 +1537,7 @@ AZURE_AI_CLAUDE_FABLE_5_1_INPUT_TEXT: Final = CLAUDE_FABLE_5_1_INPUT_TEXT.model_
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "not_available",
"speed": "standard",
},
},
),
@ -1495,6 +1576,7 @@ AZURE_AI_CLAUDE_FABLE_5_1_STREAM: Final = CLAUDE_FABLE_5_1_STREAM.model_copy(
"cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0},
"service_tier": "standard",
"inference_geo": "not_available",
"speed": "standard",
},
},
},
@ -1582,6 +1664,7 @@ AZURE_AI_CLAUDE_HAIKU_5_5_INPUT_TEXT: Final = CLAUDE_HAIKU_5_5_INPUT_TEXT.model_
"output_tokens_details": {"thinking_tokens": 0},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
"diagnostics": None,
},
@ -1624,6 +1707,7 @@ AZURE_AI_CLAUDE_HAIKU_5_5_STREAM: Final = CLAUDE_HAIKU_5_5_STREAM.model_copy(
},
"service_tier": "standard",
"inference_geo": "global",
"speed": "standard",
},
},
},
@ -1713,6 +1797,157 @@ PERPLEXITY_SONAR_NEXT_OFF_PEAK: Final = PERPLEXITY_SONAR_NEXT_NO_SEARCH.model_co
}
)
AZURE_AI_CLAUDE_FABLE_5_1_CACHE_READ: Final = _azure_ai_claude_shape_case(
CLAUDE_FABLE_5_1_CACHE_READ,
"azure_ai/claude-fable-5-1-cache_read",
"azure_ai/claude-fable-5-1",
_azure_ai_claude_usage(input_tokens=14, output_tokens=6, inference_geo="not_available", cache_read_input_tokens=27003),
ExactExpected(
spend=0.012224275,
input_cost=0.011714275,
output_cost=0.00051,
prompt_tokens=27017,
completion_tokens=6,
),
)
AZURE_AI_CLAUDE_FABLE_5_1_CACHE_WRITE_5M: Final = _azure_ai_claude_shape_case(
CLAUDE_FABLE_5_1_CACHE_WRITE_5M,
"azure_ai/claude-fable-5-1-cache_write_5m",
"azure_ai/claude-fable-5-1",
_azure_ai_claude_usage(
input_tokens=14,
output_tokens=5,
inference_geo="not_available",
cache_creation_input_tokens=27011,
ephemeral_5m_input_tokens=27011,
),
ExactExpected(
spend=0.57464675,
input_cost=0.57422175,
output_cost=0.000425,
prompt_tokens=27025,
completion_tokens=5,
),
)
AZURE_AI_CLAUDE_FABLE_5_1_CACHE_WRITE_1H: Final = _azure_ai_claude_shape_case(
CLAUDE_FABLE_5_1_CACHE_WRITE_1H,
"azure_ai/claude-fable-5-1-cache_write_1h",
"azure_ai/claude-fable-5-1",
_azure_ai_claude_usage(
input_tokens=14,
output_tokens=5,
inference_geo="not_available",
cache_creation_input_tokens=27011,
ephemeral_1h_input_tokens=27011,
),
ExactExpected(
spend=0.919037,
input_cost=0.918612,
output_cost=0.000425,
prompt_tokens=27025,
completion_tokens=5,
),
)
AZURE_AI_CLAUDE_FABLE_5_1_THINKING: Final = _azure_ai_claude_shape_case(
CLAUDE_FABLE_5_1_THINKING,
"azure_ai/claude-fable-5-1-thinking",
"azure_ai/claude-fable-5-1",
_azure_ai_claude_usage(input_tokens=18, output_tokens=99, inference_geo="not_available", thinking_tokens=33),
ExactExpected(
spend=0.008721, input_cost=0.000306, output_cost=0.008415, prompt_tokens=18, completion_tokens=99
),
[
{"type": "thinking", "thinking": "scripted thought", "signature": "scripted signature"},
{"type": "text", "text": "scripted answer for cost fixtures"},
],
adaptive_thinking=True,
)
AZURE_AI_CLAUDE_FABLE_5_1_TOOL_CALL: Final = _azure_ai_claude_shape_case(
CLAUDE_FABLE_5_1_TOOL_CALL,
"azure_ai/claude-fable-5-1-tool_call",
"azure_ai/claude-fable-5-1",
_azure_ai_claude_usage(input_tokens=385, output_tokens=50, inference_geo="not_available"),
ExactExpected(
spend=0.010795, input_cost=0.006545, output_cost=0.00425, prompt_tokens=385, completion_tokens=50
),
)
AZURE_AI_CLAUDE_HAIKU_5_5_CACHE_READ: Final = _azure_ai_claude_shape_case(
CLAUDE_HAIKU_5_5_CACHE_READ,
"azure_ai/claude-haiku-5-5-cache_read",
"azure_ai/claude-haiku-5-5",
_azure_ai_claude_usage(input_tokens=14, output_tokens=5, inference_geo="global", cache_read_input_tokens=27003),
ExactExpected(
spend=0.000520467,
input_cost=0.000515717,
output_cost=0.00000475,
prompt_tokens=27017,
completion_tokens=5,
),
)
AZURE_AI_CLAUDE_HAIKU_5_5_CACHE_WRITE_5M: Final = _azure_ai_claude_shape_case(
CLAUDE_HAIKU_5_5_CACHE_WRITE_5M,
"azure_ai/claude-haiku-5-5-cache_write_5m",
"azure_ai/claude-haiku-5-5",
_azure_ai_claude_usage(
input_tokens=14,
output_tokens=6,
inference_geo="global",
cache_creation_input_tokens=27011,
ephemeral_5m_input_tokens=27011,
),
ExactExpected(
spend=0.0064234725,
input_cost=0.0064177725,
output_cost=0.0000057,
prompt_tokens=27025,
completion_tokens=6,
),
)
AZURE_AI_CLAUDE_HAIKU_5_5_CACHE_WRITE_1H: Final = _azure_ai_claude_shape_case(
CLAUDE_HAIKU_5_5_CACHE_WRITE_1H,
"azure_ai/claude-haiku-5-5-cache_write_1h",
"azure_ai/claude-haiku-5-5",
_azure_ai_claude_usage(
input_tokens=14,
output_tokens=6,
inference_geo="global",
cache_creation_input_tokens=27011,
ephemeral_1h_input_tokens=27011,
),
ExactExpected(
spend=0.01027254,
input_cost=0.01026684,
output_cost=0.0000057,
prompt_tokens=27025,
completion_tokens=6,
),
)
AZURE_AI_CLAUDE_HAIKU_5_5_THINKING: Final = _azure_ai_claude_shape_case(
CLAUDE_HAIKU_5_5_THINKING,
"azure_ai/claude-haiku-5-5-thinking",
"azure_ai/claude-haiku-5-5",
_azure_ai_claude_usage(input_tokens=18, output_tokens=95, inference_geo="global", thinking_tokens=54),
ExactExpected(
spend=0.00009367, input_cost=0.00000342, output_cost=0.00009025, prompt_tokens=18, completion_tokens=95
),
[
{"type": "thinking", "thinking": "scripted thought", "signature": "scripted signature"},
{"type": "text", "text": "scripted answer for cost fixtures"},
],
adaptive_thinking=True,
)
AZURE_AI_CLAUDE_HAIKU_5_5_TOOL_CALL: Final = _azure_ai_claude_shape_case(
CLAUDE_HAIKU_5_5_TOOL_CALL,
"azure_ai/claude-haiku-5-5-tool_call",
"azure_ai/claude-haiku-5-5",
_azure_ai_claude_usage(input_tokens=511, output_tokens=34, inference_geo="global"),
ExactExpected(
spend=0.00012939, input_cost=0.00009709, output_cost=0.0000323, prompt_tokens=511, completion_tokens=34
),
)
CASES: Final[tuple[CostTrackingTestCase, ...]] = (
PERPLEXITY_SONAR_NEXT_OFF_PEAK,
NOVA_NEXT_TRANSCRIPTIONS_PER_SECOND,
@ -1764,8 +1999,18 @@ CASES: Final[tuple[CostTrackingTestCase, ...]] = (
XAI_GROK_4_7_INPUT_TEXT,
AZURE_AI_CLAUDE_FABLE_5_1_INPUT_TEXT,
AZURE_AI_CLAUDE_FABLE_5_1_STREAM,
AZURE_AI_CLAUDE_FABLE_5_1_CACHE_READ,
AZURE_AI_CLAUDE_FABLE_5_1_CACHE_WRITE_5M,
AZURE_AI_CLAUDE_FABLE_5_1_CACHE_WRITE_1H,
AZURE_AI_CLAUDE_FABLE_5_1_THINKING,
AZURE_AI_CLAUDE_FABLE_5_1_TOOL_CALL,
AZURE_AI_CLAUDE_HAIKU_5_5_INPUT_TEXT,
AZURE_AI_CLAUDE_HAIKU_5_5_STREAM,
AZURE_AI_CLAUDE_HAIKU_5_5_CACHE_READ,
AZURE_AI_CLAUDE_HAIKU_5_5_CACHE_WRITE_5M,
AZURE_AI_CLAUDE_HAIKU_5_5_CACHE_WRITE_1H,
AZURE_AI_CLAUDE_HAIKU_5_5_THINKING,
AZURE_AI_CLAUDE_HAIKU_5_5_TOOL_CALL,
)
PARITY: Final[tuple[StreamParityTestCase, ...]] = (

View file

@ -26,6 +26,14 @@ from integration.cost_calculation.stream_parity.case import StreamParityTestCase
from integration.cost_calculation.bridge_cost_parity.case import BridgeCostParityTestCase, bridge_pairs
def _response_for_model(response: JsonResponse, model: str) -> JsonResponse:
return response.model_copy(update={"body": {**response.body, "model": model}})
def _stream_for_model(response: SseResponse, model: str) -> SseResponse:
return response.model_copy(update={"frames": tuple(frame.replace("gpt-6-luna", model) for frame in response.frames)})
# gpt-5.3-codex
GPT_5_3_CODEX_INPUT_TEXT: Final = CostTrackingTestCase(
name="gpt-5.3-codex-input_text",
@ -11183,6 +11191,171 @@ GPT_6_ASTRA_CACHE_WRITE_5M: Final = with_response_usage(
ExactExpected(spend=0.2148, input_cost=0.192, output_cost=0.0228, prompt_tokens=12928, completion_tokens=380),
)
GPT_5_6_TERRA_INPUT_TEXT: Final = GPT_6_LUNA_INPUT_TEXT.model_copy(
update={
"name": "gpt-5.6-terra-input_text",
"model": "gpt-5.6-terra",
"response": _response_for_model(cast(JsonResponse, GPT_6_LUNA_INPUT_TEXT.response), "gpt-5.6-terra"),
"expected": ExactExpected(
spend=0.0112112,
input_cost=0.004784,
output_cost=0.0064272,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
GPT_5_6_TERRA_STREAM: Final = GPT_6_LUNA_STREAM.model_copy(
update={
"name": "gpt-5.6-terra-stream",
"model": "gpt-5.6-terra",
"response": _stream_for_model(cast(SseResponse, GPT_6_LUNA_STREAM.response), "gpt-5.6-terra"),
"expected": ExactExpected(
spend=0.0112112,
input_cost=0.004784,
output_cost=0.0064272,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
GPT_5_6_TERRA_SERVICE_TIER_FLEX: Final = GPT_6_LUNA_SERVICE_TIER_FLEX.model_copy(
update={
"name": "gpt-5.6-terra-service_tier_flex",
"model": "gpt-5.6-terra",
"response": _response_for_model(cast(JsonResponse, GPT_6_LUNA_SERVICE_TIER_FLEX.response), "gpt-5.6-terra"),
"expected": ExactExpected(
spend=0.0056056,
input_cost=0.002392,
output_cost=0.0032136,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
GPT_5_6_TERRA_SERVICE_TIER_PRIORITY: Final = GPT_6_LUNA_SERVICE_TIER_PRIORITY.model_copy(
update={
"name": "gpt-5.6-terra-service_tier_priority",
"model": "gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, GPT_6_LUNA_SERVICE_TIER_PRIORITY.response), "gpt-5.6-terra"
),
"expected": ExactExpected(
spend=0.0224224,
input_cost=0.009568,
output_cost=0.0128544,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
GPT_5_6_TERRA_RESPONSES_NATIVE_JSON: Final = GPT_6_LUNA_RESPONSES_NATIVE_JSON.model_copy(
update={
"name": "gpt-5.6-terra-responses_native_json",
"model": "gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, GPT_6_LUNA_RESPONSES_NATIVE_JSON.response), "gpt-5.6-terra"
),
"expected": ExactExpected(
spend=0.0112112,
input_cost=0.004784,
output_cost=0.0064272,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
GPT_5_6_TERRA_RESPONSES_DEPLOYMENT_JSON: Final = GPT_6_LUNA_RESPONSES_DEPLOYMENT_JSON.model_copy(
update={
"name": "gpt-5.6-terra-responses_deployment_json",
"model": "gpt-5.6-terra",
"deployment": Deployment(model="openai/responses/gpt-5.6-terra"),
"response": _response_for_model(
cast(JsonResponse, GPT_6_LUNA_RESPONSES_DEPLOYMENT_JSON.response), "gpt-5.6-terra"
),
"expected": ExactExpected(
spend=0.0112112,
input_cost=0.004784,
output_cost=0.0064272,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
GPT_5_6_TERRA_CHAT_BRIDGED_JSON: Final = GPT_6_LUNA_CHAT_BRIDGED_JSON.model_copy(
update={
"name": "gpt-5.6-terra-chat_bridged_json",
"model": "gpt-5.6-terra",
"deployment": Deployment(model="openai/responses/gpt-5.6-terra"),
"response": _response_for_model(cast(JsonResponse, GPT_6_LUNA_CHAT_BRIDGED_JSON.response), "gpt-5.6-terra"),
"expected": ExactExpected(
spend=0.0112112,
input_cost=0.004784,
output_cost=0.0064272,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
GPT_5_6_TERRA_CACHE_READ: Final = GPT_6_LUNA_CACHE_READ.model_copy(
update={
"name": "gpt-5.6-terra-cache_read",
"model": "gpt-5.6-terra",
"response": _response_for_model(cast(JsonResponse, GPT_6_LUNA_CACHE_READ.response), "gpt-5.6-terra"),
"expected": ExactExpected(
spend=0.01078688,
input_cost=0.00485888,
output_cost=0.005928,
prompt_tokens=12928,
completion_tokens=380,
),
}
)
GPT_5_6_TERRA_CACHE_WRITE_5M: Final = GPT_6_LUNA_CACHE_WRITE_5M.model_copy(
update={
"name": "gpt-5.6-terra-cache_write_5m",
"model": "gpt-5.6-terra",
"response": _response_for_model(
cast(JsonResponse, GPT_6_LUNA_CACHE_WRITE_5M.response), "gpt-5.6-terra"
),
"expected": ExactExpected(
spend=0.047528,
input_cost=0.0416,
output_cost=0.005928,
prompt_tokens=12928,
completion_tokens=380,
),
}
)
GPT_5_6_TERRA_REASONING: Final = GPT_6_LUNA_REASONING.model_copy(
update={
"name": "gpt-5.6-terra-reasoning",
"model": "gpt-5.6-terra",
"response": _response_for_model(cast(JsonResponse, GPT_6_LUNA_REASONING.response), "gpt-5.6-terra"),
"expected": ExactExpected(
spend=0.066248,
input_cost=0.003224,
output_cost=0.063024,
prompt_tokens=1240,
completion_tokens=4040,
),
}
)
GPT_5_6_TERRA_TOOL_CALL: Final = GPT_6_LUNA_TOOL_CALL.model_copy(
update={
"name": "gpt-5.6-terra-tool_call",
"model": "gpt-5.6-terra",
"response": _response_for_model(cast(JsonResponse, GPT_6_LUNA_TOOL_CALL.response), "gpt-5.6-terra"),
"expected": ExactExpected(
spend=0.0112112,
input_cost=0.004784,
output_cost=0.0064272,
prompt_tokens=1840,
completion_tokens=412,
),
}
)
GPT_5_6_SLASH_ALIAS: Final = GPT_5_6_INPUT_TEXT.model_copy(
update={"name": "gpt-5.6-slash_alias", "alias": "openai/custom/gpt-5.6-$MARKER"}
@ -11485,6 +11658,17 @@ CASES: Final[tuple[CostTrackingTestCase, ...]] = (
GPT_6_1_SOL_CACHE_WRITE_5M,
GPT_6_LUNA_CACHE_WRITE_5M,
GPT_6_ASTRA_CACHE_WRITE_5M,
GPT_5_6_TERRA_INPUT_TEXT,
GPT_5_6_TERRA_STREAM,
GPT_5_6_TERRA_RESPONSES_NATIVE_JSON,
GPT_5_6_TERRA_RESPONSES_DEPLOYMENT_JSON,
GPT_5_6_TERRA_CHAT_BRIDGED_JSON,
GPT_5_6_TERRA_CACHE_READ,
GPT_5_6_TERRA_CACHE_WRITE_5M,
GPT_5_6_TERRA_REASONING,
GPT_5_6_TERRA_SERVICE_TIER_FLEX,
GPT_5_6_TERRA_SERVICE_TIER_PRIORITY,
GPT_5_6_TERRA_TOOL_CALL,
)
PARITY: Final[tuple[StreamParityTestCase, ...]] = (
@ -11513,6 +11697,7 @@ PARITY: Final[tuple[StreamParityTestCase, ...]] = (
StreamParityTestCase(plain=GPT_6_LUNA_INPUT_TEXT, streamed=GPT_6_LUNA_STREAM),
StreamParityTestCase(plain=GPT_6_ASTRA_INPUT_TEXT, streamed=GPT_6_ASTRA_STREAM),
StreamParityTestCase(plain=GPT_6_1_SOL_INPUT_TEXT, streamed=GPT_6_1_SOL_STREAM),
StreamParityTestCase(plain=GPT_5_6_TERRA_INPUT_TEXT, streamed=GPT_5_6_TERRA_STREAM),
)
BRIDGE_COST_PARITY: Final[tuple[BridgeCostParityTestCase, ...]] = (
@ -11545,4 +11730,7 @@ BRIDGE_COST_PARITY: Final[tuple[BridgeCostParityTestCase, ...]] = (
BridgeCostParityTestCase(native=GPT_6_LUNA_RESPONSES_DEPLOYMENT_JSON, bridged=GPT_6_LUNA_CHAT_BRIDGED_JSON),
BridgeCostParityTestCase(native=GPT_6_ASTRA_RESPONSES_DEPLOYMENT_JSON, bridged=GPT_6_ASTRA_CHAT_BRIDGED_JSON),
BridgeCostParityTestCase(native=GPT_6_1_SOL_RESPONSES_DEPLOYMENT_JSON, bridged=GPT_6_1_SOL_CHAT_BRIDGED_JSON),
BridgeCostParityTestCase(
native=GPT_5_6_TERRA_RESPONSES_DEPLOYMENT_JSON, bridged=GPT_5_6_TERRA_CHAT_BRIDGED_JSON
),
)

View file

@ -2,15 +2,32 @@
PARITY pairs the streamed case with its plain twin where both bill the same row."""
from typing import Final
from typing import Final, cast
from pydantic import JsonValue
from integration.cost_calculation.cases.anthropic import (
CLAUDE_FABLE_5_1_CACHE_READ,
CLAUDE_FABLE_5_1_CACHE_WRITE_1H,
CLAUDE_FABLE_5_1_CACHE_WRITE_5M,
CLAUDE_FABLE_5_1_INPUT_TEXT,
CLAUDE_FABLE_5_1_STREAM,
CLAUDE_FABLE_5_1_THINKING,
CLAUDE_FABLE_5_1_TOOL_CALL,
CLAUDE_OPUS_5_5_CACHE_READ,
CLAUDE_OPUS_5_5_CACHE_WRITE_1H,
CLAUDE_OPUS_5_5_CACHE_WRITE_5M,
CLAUDE_OPUS_5_5_INPUT_TEXT,
CLAUDE_OPUS_5_5_STREAM,
CLAUDE_OPUS_5_5_THINKING,
CLAUDE_OPUS_5_5_TOOL_CALL,
CLAUDE_SONNET_5_5_CACHE_READ,
CLAUDE_SONNET_5_5_CACHE_WRITE_1H,
CLAUDE_SONNET_5_5_CACHE_WRITE_5M,
CLAUDE_SONNET_5_5_INPUT_TEXT,
CLAUDE_SONNET_5_5_STREAM,
CLAUDE_SONNET_5_5_THINKING,
CLAUDE_SONNET_5_5_TOOL_CALL,
)
from integration.cost_calculation.bridge_cost_parity.case import BridgeCostParityTestCase, bridge_pairs
from integration.cost_calculation.cost_tracking_case import (
@ -24,6 +41,99 @@ from integration.cost_calculation.cost_tracking_case import (
from integration.cost_calculation.stream_parity.case import StreamParityTestCase, sse_frames
def _gemini_case_response(response: JsonResponse | SseResponse, model_version: str) -> JsonResponse | SseResponse:
match response:
case JsonResponse():
return response.model_copy(update={"body": {**response.body, "modelVersion": model_version}})
case SseResponse():
return response.model_copy(
update={
"frames": tuple(frame.replace("gemini-3.8-flash", model_version) for frame in response.frames)
}
)
def _gemini_case(
sibling: CostTrackingTestCase, name: str, model: str, expected: ExactExpected
) -> CostTrackingTestCase:
return sibling.model_copy(
update={
"name": name,
"model": model,
"response": _gemini_case_response(cast(JsonResponse | SseResponse, sibling.response), "gemini-3.1-pro-preview"),
"expected": expected,
}
)
def _vertex_claude_usage(
input_tokens: int,
output_tokens: int,
*,
cache_creation_input_tokens: int = 0,
cache_read_input_tokens: int = 0,
ephemeral_5m_input_tokens: int = 0,
ephemeral_1h_input_tokens: int = 0,
thinking_tokens: int = 0,
) -> dict[str, JsonValue]:
return {
"input_tokens": input_tokens,
"cache_creation_input_tokens": cache_creation_input_tokens,
"cache_read_input_tokens": cache_read_input_tokens,
"cache_creation": {
"ephemeral_5m_input_tokens": ephemeral_5m_input_tokens,
"ephemeral_1h_input_tokens": ephemeral_1h_input_tokens,
},
"output_tokens": output_tokens,
"output_tokens_details": {"thinking_tokens": thinking_tokens},
}
def _vertex_claude_shape_case(
sibling: CostTrackingTestCase,
name: str,
model: str,
usage: dict[str, JsonValue],
expected: ExactExpected,
response_content: list[dict[str, JsonValue]] | None = None,
adaptive_thinking: bool = False,
) -> CostTrackingTestCase:
response: Final = cast(JsonResponse, sibling.response)
request: Final = (
{
**{
key: value
for key, value in sibling.request.items()
if key not in {"reasoning_effort", "allowed_openai_params"}
},
"thinking": {"type": "adaptive"},
"output_config": {"effort": "medium"},
"allowed_openai_params": ["thinking", "output_config"],
}
if adaptive_thinking
else sibling.request
)
body: Final = {
key: value
for key, value in {
**response.body,
"model": model.rsplit("/", 1)[-1],
"usage": usage,
**({"content": response_content} if response_content is not None else {}),
}.items()
if key != "diagnostics"
}
return sibling.model_copy(
update={
"name": name,
"model": model,
"request": request,
"response": response.model_copy(update={"body": body}),
"expected": expected,
}
)
def _vertex_claude_stream_response(model: str, stop_reason: str, text_deltas: tuple[str, ...]) -> SseResponse:
text_frames: Final = (
(
@ -3081,6 +3191,191 @@ VERTEX_AI_CLAUDE_FABLE_5_1_STREAM: Final = CLAUDE_FABLE_5_1_STREAM.model_copy(
}
)
VERTEX_AI_CLAUDE_SONNET_5_5_CACHE_READ: Final = _vertex_claude_shape_case(
CLAUDE_SONNET_5_5_CACHE_READ,
"vertex_ai/claude-sonnet-5-5-cache_read",
"vertex_ai/claude-sonnet-5-5",
_vertex_claude_usage(input_tokens=14, output_tokens=6, cache_read_input_tokens=27003),
ExactExpected(
spend=0.00474011, input_cost=0.00463811, output_cost=0.000102, prompt_tokens=27017, completion_tokens=6
),
)
VERTEX_AI_CLAUDE_SONNET_5_5_CACHE_WRITE_5M: Final = _vertex_claude_shape_case(
CLAUDE_SONNET_5_5_CACHE_WRITE_5M,
"vertex_ai/claude-sonnet-5-5-cache_write_5m",
"vertex_ai/claude-sonnet-5-5",
_vertex_claude_usage(
input_tokens=14, output_tokens=6, cache_creation_input_tokens=27011, ephemeral_5m_input_tokens=27011
),
ExactExpected(
spend=0.11494635, input_cost=0.11484435, output_cost=0.000102, prompt_tokens=27025, completion_tokens=6
),
)
VERTEX_AI_CLAUDE_SONNET_5_5_CACHE_WRITE_1H: Final = _vertex_claude_shape_case(
CLAUDE_SONNET_5_5_CACHE_WRITE_1H,
"vertex_ai/claude-sonnet-5-5-cache_write_1h",
"vertex_ai/claude-sonnet-5-5",
_vertex_claude_usage(
input_tokens=14, output_tokens=6, cache_creation_input_tokens=27011, ephemeral_1h_input_tokens=27011
),
ExactExpected(
spend=0.1838244, input_cost=0.1837224, output_cost=0.000102, prompt_tokens=27025, completion_tokens=6
),
)
VERTEX_AI_CLAUDE_SONNET_5_5_THINKING: Final = _vertex_claude_shape_case(
CLAUDE_SONNET_5_5_THINKING,
"vertex_ai/claude-sonnet-5-5-thinking",
"vertex_ai/claude-sonnet-5-5",
_vertex_claude_usage(input_tokens=18, output_tokens=144, thinking_tokens=37),
ExactExpected(
spend=0.0025092, input_cost=0.0000612, output_cost=0.002448, prompt_tokens=18, completion_tokens=144
),
[
{"type": "thinking", "thinking": "scripted thought", "signature": "scripted signature"},
{"type": "text", "text": "scripted answer for cost fixtures"},
],
adaptive_thinking=True,
)
VERTEX_AI_CLAUDE_SONNET_5_5_TOOL_CALL: Final = _vertex_claude_shape_case(
CLAUDE_SONNET_5_5_TOOL_CALL,
"vertex_ai/claude-sonnet-5-5-tool_call",
"vertex_ai/claude-sonnet-5-5",
_vertex_claude_usage(input_tokens=385, output_tokens=50),
ExactExpected(
spend=0.002159, input_cost=0.001309, output_cost=0.00085, prompt_tokens=385, completion_tokens=50
),
)
VERTEX_AI_CLAUDE_OPUS_5_5_CACHE_READ: Final = _vertex_claude_shape_case(
CLAUDE_OPUS_5_5_CACHE_READ,
"vertex_ai/claude-opus-5-5-cache_read",
"vertex_ai/claude-opus-5-5",
_vertex_claude_usage(input_tokens=14, output_tokens=6, cache_read_input_tokens=27003),
ExactExpected(
spend=0.01003788, input_cost=0.00982188, output_cost=0.000216, prompt_tokens=27017, completion_tokens=6
),
)
VERTEX_AI_CLAUDE_OPUS_5_5_CACHE_WRITE_5M: Final = _vertex_claude_shape_case(
CLAUDE_OPUS_5_5_CACHE_WRITE_5M,
"vertex_ai/claude-opus-5-5-cache_write_5m",
"vertex_ai/claude-opus-5-5",
_vertex_claude_usage(
input_tokens=14, output_tokens=6, cache_creation_input_tokens=27011, ephemeral_5m_input_tokens=27011
),
ExactExpected(
spend=0.2434158, input_cost=0.2431998, output_cost=0.000216, prompt_tokens=27025, completion_tokens=6
),
)
VERTEX_AI_CLAUDE_OPUS_5_5_CACHE_WRITE_1H: Final = _vertex_claude_shape_case(
CLAUDE_OPUS_5_5_CACHE_WRITE_1H,
"vertex_ai/claude-opus-5-5-cache_write_1h",
"vertex_ai/claude-opus-5-5",
_vertex_claude_usage(
input_tokens=14, output_tokens=6, cache_creation_input_tokens=27011, ephemeral_1h_input_tokens=27011
),
ExactExpected(
spend=0.3892752, input_cost=0.3890592, output_cost=0.000216, prompt_tokens=27025, completion_tokens=6
),
)
VERTEX_AI_CLAUDE_OPUS_5_5_THINKING: Final = _vertex_claude_shape_case(
CLAUDE_OPUS_5_5_THINKING,
"vertex_ai/claude-opus-5-5-thinking",
"vertex_ai/claude-opus-5-5",
_vertex_claude_usage(input_tokens=18, output_tokens=162, thinking_tokens=66),
ExactExpected(
spend=0.0059616, input_cost=0.0001296, output_cost=0.005832, prompt_tokens=18, completion_tokens=162
),
[
{"type": "thinking", "thinking": "scripted thought", "signature": "scripted signature"},
{"type": "text", "text": "scripted answer for cost fixtures"},
],
adaptive_thinking=True,
)
VERTEX_AI_CLAUDE_OPUS_5_5_TOOL_CALL: Final = _vertex_claude_shape_case(
CLAUDE_OPUS_5_5_TOOL_CALL,
"vertex_ai/claude-opus-5-5-tool_call",
"vertex_ai/claude-opus-5-5",
_vertex_claude_usage(input_tokens=385, output_tokens=50),
ExactExpected(
spend=0.004572, input_cost=0.002772, output_cost=0.0018, prompt_tokens=385, completion_tokens=50
),
)
VERTEX_AI_CLAUDE_FABLE_5_1_CACHE_READ: Final = _vertex_claude_shape_case(
CLAUDE_FABLE_5_1_CACHE_READ,
"vertex_ai/claude-fable-5-1-cache_read",
"vertex_ai/claude-fable-5-1",
_vertex_claude_usage(input_tokens=14, output_tokens=5, cache_read_input_tokens=27003),
ExactExpected(
spend=0.013567425, input_cost=0.013092425, output_cost=0.000475, prompt_tokens=27017, completion_tokens=5
),
)
VERTEX_AI_CLAUDE_FABLE_5_1_CACHE_WRITE_5M: Final = _vertex_claude_shape_case(
CLAUDE_FABLE_5_1_CACHE_WRITE_5M,
"vertex_ai/claude-fable-5-1-cache_write_5m",
"vertex_ai/claude-fable-5-1",
_vertex_claude_usage(
input_tokens=14, output_tokens=5, cache_creation_input_tokens=27011, ephemeral_5m_input_tokens=27011
),
ExactExpected(
spend=0.64225225, input_cost=0.64177725, output_cost=0.000475, prompt_tokens=27025, completion_tokens=5
),
)
VERTEX_AI_CLAUDE_FABLE_5_1_CACHE_WRITE_1H: Final = _vertex_claude_shape_case(
CLAUDE_FABLE_5_1_CACHE_WRITE_1H,
"vertex_ai/claude-fable-5-1-cache_write_1h",
"vertex_ai/claude-fable-5-1",
_vertex_claude_usage(
input_tokens=14, output_tokens=5, cache_creation_input_tokens=27011, ephemeral_1h_input_tokens=27011
),
ExactExpected(
spend=1.027159, input_cost=1.026684, output_cost=0.000475, prompt_tokens=27025, completion_tokens=5
),
)
VERTEX_AI_CLAUDE_FABLE_5_1_THINKING: Final = _vertex_claude_shape_case(
CLAUDE_FABLE_5_1_THINKING,
"vertex_ai/claude-fable-5-1-thinking",
"vertex_ai/claude-fable-5-1",
_vertex_claude_usage(input_tokens=18, output_tokens=98, thinking_tokens=33),
ExactExpected(
spend=0.009652, input_cost=0.000342, output_cost=0.00931, prompt_tokens=18, completion_tokens=98
),
[
{"type": "thinking", "thinking": "scripted thought", "signature": "scripted signature"},
{"type": "text", "text": "scripted answer for cost fixtures"},
],
adaptive_thinking=True,
)
VERTEX_AI_CLAUDE_FABLE_5_1_TOOL_CALL: Final = _vertex_claude_shape_case(
CLAUDE_FABLE_5_1_TOOL_CALL,
"vertex_ai/claude-fable-5-1-tool_call",
"vertex_ai/claude-fable-5-1",
_vertex_claude_usage(input_tokens=385, output_tokens=50),
ExactExpected(
spend=0.012065, input_cost=0.007315, output_cost=0.00475, prompt_tokens=385, completion_tokens=50
),
)
GEMINI_3_1_PRO_PREVIEW_INPUT_TEXT: Final = _gemini_case(
GEMINI_3_8_FLASH_INPUT_TEXT, "gemini-3.1-pro-preview-input_text", "gemini-3.1-pro-preview",
ExactExpected(spend=0.0094864, input_cost=0.004048, output_cost=0.0054384, prompt_tokens=1840, completion_tokens=412)
)
GEMINI_3_1_PRO_PREVIEW_STREAM: Final = _gemini_case(
GEMINI_3_8_FLASH_STREAM, "gemini-3.1-pro-preview-stream", "gemini-3.1-pro-preview",
ExactExpected(spend=0.0094864, input_cost=0.004048, output_cost=0.0054384, prompt_tokens=1840, completion_tokens=412)
)
GEMINI_3_1_PRO_PREVIEW_CACHE_READ: Final = _gemini_case(
GEMINI_3_8_FLASH_CACHE_READ, "gemini-3.1-pro-preview-cache_read", "gemini-3.1-pro-preview",
ExactExpected(spend=0.00912736, input_cost=0.00411136, output_cost=0.005016, prompt_tokens=12928, completion_tokens=380)
)
GEMINI_3_1_PRO_PREVIEW_REASONING: Final = _gemini_case(
GEMINI_3_8_FLASH_FALLBACK_REASONING_AT_OUTPUT_RATE, "gemini-3.1-pro-preview-reasoning", "gemini-3.1-pro-preview",
ExactExpected(spend=0.056056, input_cost=0.002728, output_cost=0.053328, prompt_tokens=1240, completion_tokens=4040)
)
GEMINI_3_1_PRO_PREVIEW_TOOL_CALL: Final = _gemini_case(
GEMINI_3_8_FLASH_TOOL_CALL, "gemini-3.1-pro-preview-tool_call", "gemini-3.1-pro-preview",
ExactExpected(spend=0.0094864, input_cost=0.004048, output_cost=0.0054384, prompt_tokens=1840, completion_tokens=412)
)
CASES: Final[tuple[CostTrackingTestCase, ...]] = (
GEMINI_3_1_PRO_INPUT_TEXT,
@ -3137,6 +3432,26 @@ CASES: Final[tuple[CostTrackingTestCase, ...]] = (
VERTEX_AI_CLAUDE_OPUS_5_5_STREAM,
VERTEX_AI_CLAUDE_FABLE_5_1_INPUT_TEXT,
VERTEX_AI_CLAUDE_FABLE_5_1_STREAM,
VERTEX_AI_CLAUDE_SONNET_5_5_CACHE_READ,
VERTEX_AI_CLAUDE_SONNET_5_5_CACHE_WRITE_5M,
VERTEX_AI_CLAUDE_SONNET_5_5_CACHE_WRITE_1H,
VERTEX_AI_CLAUDE_SONNET_5_5_THINKING,
VERTEX_AI_CLAUDE_SONNET_5_5_TOOL_CALL,
VERTEX_AI_CLAUDE_OPUS_5_5_CACHE_READ,
VERTEX_AI_CLAUDE_OPUS_5_5_CACHE_WRITE_5M,
VERTEX_AI_CLAUDE_OPUS_5_5_CACHE_WRITE_1H,
VERTEX_AI_CLAUDE_OPUS_5_5_THINKING,
VERTEX_AI_CLAUDE_OPUS_5_5_TOOL_CALL,
VERTEX_AI_CLAUDE_FABLE_5_1_CACHE_READ,
VERTEX_AI_CLAUDE_FABLE_5_1_CACHE_WRITE_5M,
VERTEX_AI_CLAUDE_FABLE_5_1_CACHE_WRITE_1H,
VERTEX_AI_CLAUDE_FABLE_5_1_THINKING,
VERTEX_AI_CLAUDE_FABLE_5_1_TOOL_CALL,
GEMINI_3_1_PRO_PREVIEW_INPUT_TEXT,
GEMINI_3_1_PRO_PREVIEW_STREAM,
GEMINI_3_1_PRO_PREVIEW_CACHE_READ,
GEMINI_3_1_PRO_PREVIEW_REASONING,
GEMINI_3_1_PRO_PREVIEW_TOOL_CALL,
)
PARITY: Final[tuple[StreamParityTestCase, ...]] = (
@ -3157,9 +3472,13 @@ PARITY: Final[tuple[StreamParityTestCase, ...]] = (
),
StreamParityTestCase(plain=VERTEX_AI_CLAUDE_OPUS_5_5_INPUT_TEXT, streamed=VERTEX_AI_CLAUDE_OPUS_5_5_STREAM),
StreamParityTestCase(plain=VERTEX_AI_CLAUDE_FABLE_5_1_INPUT_TEXT, streamed=VERTEX_AI_CLAUDE_FABLE_5_1_STREAM),
StreamParityTestCase(plain=GEMINI_3_1_PRO_PREVIEW_INPUT_TEXT, streamed=GEMINI_3_1_PRO_PREVIEW_STREAM),
)
BRIDGE_COST_PARITY: Final[tuple[BridgeCostParityTestCase, ...]] = bridge_pairs(
(GEMINI_3_8_FLASH_INPUT_TEXT, GEMINI_3_8_FLASH_CACHE_READ, GEMINI_3_8_FLASH_STREAM),
("/v1/responses", "/v1/messages"),
BRIDGE_COST_PARITY: Final[tuple[BridgeCostParityTestCase, ...]] = (
*bridge_pairs(
(GEMINI_3_8_FLASH_INPUT_TEXT, GEMINI_3_8_FLASH_CACHE_READ, GEMINI_3_8_FLASH_STREAM),
("/v1/responses", "/v1/messages"),
),
*bridge_pairs((GEMINI_3_1_PRO_PREVIEW_INPUT_TEXT,), ("/v1/responses",)),
)

View file

@ -32,6 +32,41 @@ COST_MAP_ENTRIES: Final[dict[str, dict[str, JsonValue]]] = {
"input_cost_per_token": 3.2e-06,
"output_cost_per_token": 1.6e-05,
},
"gpt-5.6-terra": {
"cache_creation_input_token_cost": 3.25e-06,
"cache_creation_input_token_cost_above_272k_tokens": 6.5e-06,
"cache_creation_input_token_cost_above_272k_tokens_flex": 3.25e-06,
"cache_creation_input_token_cost_above_272k_tokens_priority": 1.3e-05,
"cache_creation_input_token_cost_flex": 1.625e-06,
"cache_creation_input_token_cost_priority": 6.5e-06,
"cache_read_input_token_cost": 2.6e-07,
"cache_read_input_token_cost_above_272k_tokens": 5.2e-07,
"cache_read_input_token_cost_above_272k_tokens_flex": 2.6e-07,
"cache_read_input_token_cost_above_272k_tokens_priority": 1.04e-06,
"cache_read_input_token_cost_flex": 1.3e-07,
"cache_read_input_token_cost_priority": 5.2e-07,
"input_cost_per_token": 2.6e-06,
"input_cost_per_token_above_272k_tokens": 5.2e-06,
"input_cost_per_token_above_272k_tokens_flex": 2.6e-06,
"input_cost_per_token_above_272k_tokens_priority": 1.04e-05,
"input_cost_per_token_flex": 1.3e-06,
"input_cost_per_token_priority": 5.2e-06,
"litellm_provider": "openai",
"max_input_tokens": 922000,
"max_output_tokens": 128000,
"max_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 1.56e-05,
"output_cost_per_token_above_272k_tokens": 2.34e-05,
"output_cost_per_token_above_272k_tokens_flex": 1.17e-05,
"output_cost_per_token_above_272k_tokens_priority": 4.68e-05,
"output_cost_per_token_flex": 7.8e-06,
"output_cost_per_token_priority": 3.12e-05,
"supports_function_calling": True,
"supports_none_reasoning_effort": True,
"supports_prompt_caching": True,
"supports_reasoning": True,
},
"gpt-6-luna": {
"output_cost_per_token_priority": 1e-06,
"input_cost_per_token_priority": 2e-07,
@ -407,8 +442,55 @@ COST_MAP_ENTRIES: Final[dict[str, dict[str, JsonValue]]] = {
"supports_function_calling": True,
"web_search_billing_unit": "per_query",
},
"gemini/gemini-4-argon": {
"cache_read_input_token_cost": 1.1e-07,
"cache_read_input_token_cost_flex": 5.5e-08,
"cache_read_input_token_cost_priority": 1.98e-07,
"input_cost_per_token": 2.2e-06,
"input_cost_per_token_flex": 1.1e-06,
"input_cost_per_token_priority": 3.96e-06,
"litellm_provider": "gemini",
"max_input_tokens": 1048576,
"max_output_tokens": 1048576,
"max_tokens": 1048576,
"mode": "chat",
"output_cost_per_reasoning_token": 1.1e-05,
"output_cost_per_token": 1.1e-05,
"output_cost_per_token_flex": 5.5e-06,
"output_cost_per_token_priority": 1.98e-05,
"supports_function_calling": True,
"supports_prompt_caching": True,
"supports_reasoning": True,
},
"gemini/gemini-3.1-pro-preview": {
"cache_read_input_token_cost": 2.6e-07,
"cache_read_input_token_cost_above_200k_tokens": 5.2e-07,
"input_cost_per_token": 2.6e-06,
"input_cost_per_token_above_200k_tokens": 5.2e-06,
"litellm_provider": "gemini",
"max_input_tokens": 1048576,
"max_output_tokens": 65536,
"max_tokens": 65536,
"mode": "chat",
"output_cost_per_token": 1.56e-05,
"output_cost_per_token_above_200k_tokens": 2.34e-05,
"supports_function_calling": True,
"supports_prompt_caching": True,
"supports_reasoning": True,
"input_cost_per_token_priority": 4.68e-06,
"input_cost_per_token_above_200k_tokens_priority": 9.36e-06,
"output_cost_per_token_priority": 2.808e-05,
"output_cost_per_token_above_200k_tokens_priority": 4.212e-05,
"cache_read_input_token_cost_priority": 4.68e-07,
"cache_read_input_token_cost_above_200k_tokens_priority": 9.36e-07,
"cache_read_input_token_cost_flex": 2.6e-07,
"input_cost_per_token_flex": 1.3e-06,
"output_cost_per_token_flex": 7.8e-06,
},
"gemini/gemini-3.8-flash": {
"cache_read_input_token_cost": 5e-08,
"cache_read_input_token_cost_flex": 2.5e-08,
"cache_read_input_token_cost_priority": 9e-08,
"google_maps_grounding_cost_per_query": 0.025,
"input_cost_per_audio_token": 1e-06,
"input_cost_per_image_token": 5.5e-07,
@ -454,8 +536,36 @@ COST_MAP_ENTRIES: Final[dict[str, dict[str, JsonValue]]] = {
"supports_function_calling": True,
"web_search_billing_unit": "per_query",
},
"gemini-3.1-pro-preview": {
"cache_creation_input_token_cost_above_200k_tokens": 2.75e-07,
"cache_read_input_token_cost": 2.2e-07,
"cache_read_input_token_cost_above_200k_tokens": 4.4e-07,
"cache_read_input_token_cost_above_200k_tokens_priority": 7.92e-07,
"cache_read_input_token_cost_priority": 3.96e-07,
"input_cost_per_token": 2.2e-06,
"input_cost_per_token_above_200k_tokens": 4.4e-06,
"input_cost_per_token_above_200k_tokens_priority": 7.92e-06,
"input_cost_per_token_flex": 1.1e-06,
"input_cost_per_token_priority": 3.96e-06,
"litellm_provider": "vertex_ai-language-models",
"max_input_tokens": 1048576,
"max_output_tokens": 65536,
"max_tokens": 65536,
"mode": "chat",
"output_cost_per_image": 0.000132,
"output_cost_per_token": 1.32e-05,
"output_cost_per_token_above_200k_tokens": 1.98e-05,
"output_cost_per_token_above_200k_tokens_priority": 3.564e-05,
"output_cost_per_token_flex": 6.6e-06,
"output_cost_per_token_priority": 2.376e-05,
"supports_function_calling": True,
"supports_prompt_caching": True,
"supports_reasoning": True,
},
"gemini-3.8-flash": {
"cache_read_input_token_cost": 5.2e-08,
"cache_read_input_token_cost_flex": 2.6e-08,
"cache_read_input_token_cost_priority": 9.36e-08,
"google_maps_grounding_cost_per_query": 0.025,
"input_cost_per_audio_token": 1.04e-06,
"input_cost_per_token": 5.2e-07,
@ -1259,6 +1369,41 @@ COST_MAP_ENTRIES: Final[dict[str, dict[str, JsonValue]]] = {
"output_cost_per_token_above_272k_tokens_priority": 4.6e-05,
"cache_read_input_token_cost_above_272k_tokens": 4.6e-07,
},
"azure/gpt-5.6-terra": {
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_272k_tokens": 5.5e-06,
"cache_creation_input_token_cost_above_272k_tokens_flex": 2.75e-06,
"cache_creation_input_token_cost_priority": 5.5e-06,
"cache_creation_input_token_cost_above_272k_tokens_priority": 1.1e-05,
"cache_creation_input_token_cost_flex": 1.375e-06,
"cache_read_input_token_cost": 2.2e-07,
"cache_read_input_token_cost_above_272k_tokens": 4.4e-07,
"cache_read_input_token_cost_above_272k_tokens_flex": 2.2e-07,
"cache_read_input_token_cost_priority": 4.4e-07,
"cache_read_input_token_cost_above_272k_tokens_priority": 8.8e-07,
"cache_read_input_token_cost_flex": 1.1e-07,
"input_cost_per_token": 2.2e-06,
"input_cost_per_token_above_272k_tokens": 4.4e-06,
"input_cost_per_token_above_272k_tokens_flex": 2.2e-06,
"input_cost_per_token_priority": 4.4e-06,
"input_cost_per_token_above_272k_tokens_priority": 8.8e-06,
"input_cost_per_token_flex": 1.1e-06,
"litellm_provider": "azure",
"max_input_tokens": 922000,
"max_output_tokens": 128000,
"max_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 1.32e-05,
"output_cost_per_token_above_272k_tokens": 1.98e-05,
"output_cost_per_token_above_272k_tokens_flex": 9.9e-06,
"output_cost_per_token_priority": 2.64e-05,
"output_cost_per_token_above_272k_tokens_priority": 3.96e-05,
"output_cost_per_token_flex": 6.6e-06,
"supports_function_calling": True,
"supports_prompt_caching": True,
"supports_reasoning": True,
"supports_none_reasoning_effort": True,
},
"azure/gpt-6-luna": {
"cache_read_input_token_cost": 1.3e-08,
"cache_creation_input_token_cost": 1.625e-07,