mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-29 06:33:28 +00:00
* 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>
40 lines
1.4 KiB
Python
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"
|