fix: python 3.10 typing compatibility in compact editor and claude 3 cache pricing (#38076, #38056)

This commit is contained in:
Alphaxiaoteng 2026-08-25 16:33:36 +08:00 committed by Alpha Intelligence
parent 947dbbf029
commit 2b5c4e2b11
5 changed files with 113 additions and 5 deletions

View file

@ -13,8 +13,14 @@ Mirrors Anthropic's native ``compact_20260112`` for non-Anthropic providers:
"""
import re
import sys
from collections.abc import Mapping, Sequence
from typing import TYPE_CHECKING, Any, Final, Literal, NotRequired, Optional, TypedDict, Union, cast
from typing import TYPE_CHECKING, Any, Final, Literal, Optional, TypedDict, Union, cast
if sys.version_info >= (3, 11):
from typing import NotRequired
else:
from typing_extensions import NotRequired
from typing_extensions import ReadOnly

View file

@ -12269,7 +12269,7 @@
},
"claude-3-haiku-20240307": {
"cache_creation_input_token_cost": 3e-07,
"cache_creation_input_token_cost_above_1hr": 6e-06,
"cache_creation_input_token_cost_above_1hr": 5e-07,
"cache_read_input_token_cost": 3e-08,
"deprecation_date": "2026-04-20",
"input_cost_per_token": 2.5e-07,
@ -12288,7 +12288,7 @@
},
"claude-3-opus-20240229": {
"cache_creation_input_token_cost": 1.875e-05,
"cache_creation_input_token_cost_above_1hr": 6e-06,
"cache_creation_input_token_cost_above_1hr": 3e-05,
"cache_read_input_token_cost": 1.5e-06,
"deprecation_date": "2026-01-05",
"input_cost_per_token": 1.5e-05,

View file

@ -12269,7 +12269,7 @@
},
"claude-3-haiku-20240307": {
"cache_creation_input_token_cost": 3e-07,
"cache_creation_input_token_cost_above_1hr": 6e-06,
"cache_creation_input_token_cost_above_1hr": 5e-07,
"cache_read_input_token_cost": 3e-08,
"deprecation_date": "2026-04-20",
"input_cost_per_token": 2.5e-07,
@ -12288,7 +12288,7 @@
},
"claude-3-opus-20240229": {
"cache_creation_input_token_cost": 1.875e-05,
"cache_creation_input_token_cost_above_1hr": 6e-06,
"cache_creation_input_token_cost_above_1hr": 3e-05,
"cache_read_input_token_cost": 1.5e-06,
"deprecation_date": "2026-01-05",
"input_cost_per_token": 1.5e-05,

View file

@ -0,0 +1,49 @@
"""
Unit tests for Python 3.10+ typing compatibility in context management compact editor.
Fixes Issue #38076:
- Verifies that NotRequired is correctly imported either from typing (>= 3.11) or typing_extensions (< 3.11).
- Verifies that _SummaryCallKwargs TypedDict definition is valid across Python versions.
"""
import importlib
import sys
def test_compact_editor_not_required_import():
"""Verify that compact.py imports NotRequired correctly based on sys.version_info."""
import litellm.llms.anthropic.experimental_pass_through.context_management.editors.compact as compact_module
assert hasattr(compact_module, "NotRequired")
if sys.version_info >= (3, 11):
import typing
assert compact_module.NotRequired is typing.NotRequired
else:
import typing_extensions
assert compact_module.NotRequired is typing_extensions.NotRequired
def test_compact_editor_summary_call_kwargs_definition():
"""Verify that _SummaryCallKwargs TypedDict is properly constructed."""
from litellm.llms.anthropic.experimental_pass_through.context_management.editors.compact import (
_SummaryCallKwargs,
)
annotations = _SummaryCallKwargs.__annotations__
assert "model" in annotations
assert "messages" in annotations
assert "max_tokens" in annotations
assert "timeout" in annotations
assert "litellm_metadata" in annotations
assert "user" in annotations
assert "allowed_model_region" in annotations
def test_compact_module_can_be_imported():
"""Ensure litellm compact module imports without error on the current runtime."""
compact_module = importlib.import_module(
"litellm.llms.anthropic.experimental_pass_through.context_management.editors.compact"
)
assert compact_module is not None

View file

@ -0,0 +1,53 @@
"""
Unit tests for Claude 3 cache creation pricing above 1 hour in model prices map.
Fixes Issue #38056:
- claude-3-haiku-20240307 cache_creation_input_token_cost_above_1hr should be 5e-07 (2x input cost of 2.5e-07)
- claude-3-opus-20240229 cache_creation_input_token_cost_above_1hr should be 3e-05 (2x input cost of 1.5e-05)
"""
import json
from pathlib import Path
import pytest
REPO_ROOT = Path(__file__).parents[2]
MAIN_PATH = REPO_ROOT / "model_prices_and_context_window.json"
BACKUP_PATH = REPO_ROOT / "litellm" / "model_prices_and_context_window_backup.json"
def _load_prices(path: Path) -> dict:
with open(path) as f:
return json.load(f)
@pytest.mark.parametrize("path", [MAIN_PATH, BACKUP_PATH], ids=["main", "backup"])
def test_claude_3_haiku_cache_creation_cost_above_1hr(path: Path):
prices = _load_prices(path)
model = "claude-3-haiku-20240307"
assert model in prices, f"{model} not found in {path}"
model_info = prices[model]
input_cost = model_info["input_cost_per_token"]
assert input_cost == 2.5e-07
# Cache creation cost above 1hr is 2x standard input cost (5e-07)
expected_cache_creation_above_1hr = input_cost * 2
assert model_info["cache_creation_input_token_cost_above_1hr"] == expected_cache_creation_above_1hr
assert model_info["cache_creation_input_token_cost_above_1hr"] == 5e-07
@pytest.mark.parametrize("path", [MAIN_PATH, BACKUP_PATH], ids=["main", "backup"])
def test_claude_3_opus_cache_creation_cost_above_1hr(path: Path):
prices = _load_prices(path)
model = "claude-3-opus-20240229"
assert model in prices, f"{model} not found in {path}"
model_info = prices[model]
input_cost = model_info["input_cost_per_token"]
assert input_cost == 1.5e-05
# Cache creation cost above 1hr is 2x standard input cost (3e-05)
expected_cache_creation_above_1hr = input_cost * 2
assert model_info["cache_creation_input_token_cost_above_1hr"] == expected_cache_creation_above_1hr
assert model_info["cache_creation_input_token_cost_above_1hr"] == 3e-05