litellm/tests/integration/_support/timing.py
Mateo Wang f3904e2e65 feat(typesafe): support Jev 1.14 images, box questions, and long-context headers (#46596)
* feat(typesafe): support Jev 1.14 images, box questions, and long-context headers

* fix(cost): drop the typesafe/jev-1.14.0 entry main already prices

* fix(typesafe): send images only with the images header and box questions only to models that answer them

TypeSafe takes assets and input_image parts only when the request carries
TypeSafe-Danger-Zone-Images: true, so without it they follow drop_params like
any other provider that cannot take images. Box support now comes from a
supports_box_questions cost-map flag set on jev-1.14.0 and jev-preview, so
jev-1.13.0 and jev-latest refuse or drop a box question before the call. A
malformed provider_specific_header answers 400 instead of 500.

* fix(typesafe): allow null box confidence and validate asset references and base64

* fix(typesafe): gate box questions on the images header, drop unreadable assets under drop_params, forward opt-in headers on the pass-through

---------

Backport of #46596 to rc/1.106.0
Cherry-picked from 3fec5075fa (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-15 06:32:44 +00:00

40 lines
1.4 KiB
Python

import time
from collections.abc import Callable, Iterable
from dataclasses import dataclass
from typing import Final
@dataclass(frozen=True, slots=True)
class Timed[T]:
value: T
seconds: float
def timed[T](operation: Callable[[], T]) -> Timed[T]:
started: Final = time.monotonic()
value: Final = operation()
return Timed(value, time.monotonic() - started)
def assert_not_delayed_by(observed: Iterable[float], *, control: Iterable[float], injected_delay: float) -> None:
worst: Final = max(observed)
baseline: Final = max(control)
assert worst < baseline + injected_delay, (
f"slowest call took {worst:.2f}s, at least the {baseline:.2f}s control plus the {injected_delay}s injected delay"
)
def assert_cut_short(elapsed: float, *, injected_delay: float) -> None:
assert elapsed < injected_delay, (
f"returned after {elapsed:.2f}s, no sooner than the {injected_delay}s injected delay"
)
def assert_enforced_within(elapsed: float, *, configured: float, slack: float, not_before: float = 0.0) -> None:
assert not_before <= elapsed <= configured + slack, (
f"took {elapsed:.2f}s, expected between {not_before}s and the configured {configured}s plus {slack}s of slack"
)
def assert_within_factor_of_control(observed: float, *, control: float, factor: float) -> None:
assert observed <= factor * control, f"took {observed:.2f}s, over {factor}x the {control:.2f}s control"