mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-05 08:07:05 +00:00
* refactor(python-bridge): split non-streaming bridge modules * refactor(python-bridge): bring shared function tracing into route layer * feat(dev): list Python route functions and call sites * feat(dev): list Rust route functions and call sites * docs(dev): record OCR parity gaps across Python and Rust * feat(dev): list executed SDK calls with runtime tracing * feat(dev): report Python vs Rust SDK pipeline steps in one CLI * feat(dev): side-by-side pipeline step report in compare CLI * fix(dev): drop invalid Final annotations in compare cell loop * feat(dev): blue python-only and yellow rust-only steps in compare CLI * feat(dev): vertical layout with section spacing in compare CLI * fix(dev): validate SDK trace stages across sync and async routes * refactor(rust): align SDK route call structure with Python * refactor(python-bridge): share sync and async route call wrappers * refactor(dev): split compare CLI into fixtures, runtime, and report modules * fix(ci): run SDK trace tests and satisfy test lint
39 lines
1.4 KiB
Python
39 lines
1.4 KiB
Python
from __future__ import annotations
|
|
|
|
from collections.abc import Callable, Sequence
|
|
from dataclasses import dataclass
|
|
from types import FunctionType
|
|
from typing import Final, cast
|
|
|
|
from tests.sdk_function_trace.profiler import FunctionTraceEvent, profile_python
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class TraceStep:
|
|
function: FunctionType
|
|
depth: int
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class TraceScenario:
|
|
steps: tuple[TraceStep, ...]
|
|
invoke_python: Callable[[], object]
|
|
invoke_rust: Callable[[], Sequence[FunctionTraceEvent]]
|
|
|
|
|
|
def assert_function_trace_parity(scenario: TraceScenario) -> None:
|
|
expected: Final = tuple(
|
|
FunctionTraceEvent(function=step.function.__name__, depth=step.depth) for step in scenario.steps
|
|
)
|
|
functions: Final = cast(tuple[FunctionType, ...], tuple(step.function for step in scenario.steps))
|
|
with profile_python(functions) as profiler:
|
|
scenario.invoke_python()
|
|
python_trace: Final = tuple(profiler.events)
|
|
rust_trace: Final = tuple(scenario.invoke_rust())
|
|
|
|
if python_trace != expected:
|
|
raise AssertionError(f"Python function trace differs: {python_trace!r} != {expected!r}")
|
|
if rust_trace != expected:
|
|
raise AssertionError(f"Rust function trace differs: {rust_trace!r} != {expected!r}")
|
|
if python_trace != rust_trace:
|
|
raise AssertionError(f"Python and Rust function traces differ: {python_trace!r} != {rust_trace!r}")
|