mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-13 03:59:12 +00:00
* feat(lens): consume the independent Lens service and shared UI * fix(lens): keep embedded setup stable and vendor UI before builds * chore(lens): pin embedded UI provenance to published Lens source * fix(lens): complete embedded UI extraction across CI builds * docs(lens): record latest main and removal-boundary validation * fix(lens): wire external chart credentials and ingestion modes * test(lens): cover adapter failures and fix extraction CI * docs(lens): refresh bundled chart setup instructions * test(lens): restore gateway adapter test package marker * build(lens): pin clean-cut UI and supported storage chart * test(ui): await guardrail scope menu before checking options * perf(lens): omit unused trace-team lookup from product requests * docs(lens): record final-image adapter permission checks * test(lens): assert delegated investigation authorization * refactor(lens): remove copied trace runtime and preserve spend logging * test(lens): verify independent gateway image upgrades and outages * test(lens): pin the chart qualification database image * fix(lens): update embedded UI metadata filters * test: wait for Lens chart pod identity convergence * fix(e2e): select Lens chart pods by deployment ownership * fix(e2e): select Helm migration ownership for Lens upgrades * test(lens): retain migration Jobs through rollout assertions * docs(helm): require existing database for migration hooks * test(lens): qualify release boundaries with embedded navigation update * docs(lens): record browser qualification for embedded tabs * fix(lens): remove unrelated CI and guardrail test changes * test(lens): give qualification tenants unique key aliases * feat(lens): embed the latest canonical Lens interface * fix(lens): qualify split inference through the gateway * fix(lens): preserve scoped auth and isolate delegated credentials * chore(lens): remove unrelated documentation and lint changes * fix(lens): bound concurrent forwarding buffers through response delivery * fix(lens): preserve OAuth2 dispatch without inference policies * chore(lens): adopt current shared onboarding UI * fix(lens): refresh shared setup UI and review context * fix(lens): bound uploads before gateway authentication * docs(lens): remove extraction evidence from the gateway repo * docs(lens): refresh shared setup prompt for paired releases
58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
from typing import Final
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from litellm.tracing.queries import TRACE_AGENTS
|
|
|
|
|
|
@pytest.mark.parametrize("count", (0, "9007199254740993", 2**64 - 1))
|
|
def test_agent_rows_normalize_counts_without_precision_loss(count: int | str) -> None:
|
|
result: Final = TRACE_AGENTS.response.validate_python(
|
|
{"data": [{"agent_name": "agent", "runs": count, "failed_runs": 0, "last_seen_ms": 1, "frameworks": ["otel"]}]}
|
|
)
|
|
row: Final = result.data[0]
|
|
assert row.runs == int(count)
|
|
assert row.frameworks == ("otel",)
|
|
with pytest.raises(ValidationError):
|
|
row.agent_name = "changed"
|
|
|
|
|
|
@pytest.mark.parametrize("count", (-1, "18446744073709551616", "1.5"))
|
|
def test_agent_rows_reject_invalid_counts(count: int | str) -> None:
|
|
with pytest.raises(ValidationError):
|
|
TRACE_AGENTS.response.validate_python(
|
|
{"data": [{"agent_name": "agent", "runs": count, "failed_runs": 0, "last_seen_ms": 1}]}
|
|
)
|
|
|
|
|
|
def test_dictionary_validation_keeps_required_nullable_and_optional_fields_distinct() -> None:
|
|
from pydantic import TypeAdapter
|
|
|
|
from litellm.tracing.generated.types import SpanDetail, SpanErrorPage
|
|
|
|
result: Final = TypeAdapter(SpanDetail).validate_python(
|
|
{
|
|
"span_id": "span",
|
|
"input": "",
|
|
"output": "",
|
|
"attributes": {"key": "value"},
|
|
"input_ui": {"kind": "messages", "messages": [{"role": "user", "content": "hello"}]},
|
|
"output_ui": {"kind": "text", "text": "answer"},
|
|
}
|
|
)
|
|
assert result["input_ui"] == {"kind": "messages", "messages": ({"role": "user", "content": "hello"},)}
|
|
assert result["attributes"] == {"key": "value"}
|
|
assert (
|
|
TypeAdapter(SpanErrorPage).validate_python(
|
|
{
|
|
"span_id": "span",
|
|
"message": "error",
|
|
"total_chars": 5,
|
|
"next_cursor": None,
|
|
}
|
|
)["next_cursor"]
|
|
is None
|
|
)
|
|
with pytest.raises(ValidationError):
|
|
TypeAdapter(SpanErrorPage).validate_python({"span_id": "span", "message": "error", "total_chars": 5})
|