Repository navigation
feat(ui): agent traces open in a side drawer with a chat-style run view #43972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
6d5d2ae
4d02702
96c4e6a
0a7dc5f
556e8c2
11a0824
0763c01
0f8c043
27110aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| """Per-convention span normalizers, tried in order: the first whose `matches()` is true wins.""" | ||
|
|
||
| from collections.abc import Mapping, Sequence | ||
| from typing import Final | ||
|
|
||
| from litellm.tracing.normalizers.base import SpanNormalizer | ||
| from litellm.tracing.normalizers.genai import GenAISemconvNormalizer | ||
| from litellm.tracing.normalizers.langsmith import LangSmithNormalizer | ||
| from litellm.tracing.normalizers.openinference import OpenInferenceNormalizer | ||
|
|
||
| NORMALIZERS: Final[tuple[SpanNormalizer, ...]] = ( | ||
| LangSmithNormalizer(), | ||
| OpenInferenceNormalizer(), | ||
| GenAISemconvNormalizer(), | ||
| ) | ||
| _FALLBACK: Final[SpanNormalizer] = GenAISemconvNormalizer() | ||
|
|
||
|
|
||
| def select_normalizer( | ||
| scope_name: str, attributes: Mapping[str, str], registry: Sequence[SpanNormalizer] = NORMALIZERS | ||
| ) -> SpanNormalizer: | ||
| return next((n for n in registry if n.matches(scope_name, attributes)), _FALLBACK) | ||
|
|
||
|
|
||
| __all__ = ( | ||
| "NORMALIZERS", | ||
| "GenAISemconvNormalizer", | ||
| "LangSmithNormalizer", | ||
| "OpenInferenceNormalizer", | ||
| "SpanNormalizer", | ||
| "select_normalizer", | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| from collections.abc import Mapping | ||
| from typing import Protocol | ||
|
|
||
| from litellm.tracing.types import SpanRow | ||
|
|
||
|
|
||
| class SpanNormalizer(Protocol): | ||
| """Maps one tracing convention's span attributes onto the LiteLLM `SpanRow` columns.""" | ||
|
|
||
| @property | ||
| def name(self) -> str: ... | ||
|
|
||
| def matches(self, scope_name: str, attributes: Mapping[str, str]) -> bool: ... | ||
|
|
||
| def normalize(self, row: SpanRow, attributes: Mapping[str, str]) -> None: ... | ||
|
|
||
|
|
||
| def to_int(value: str | None) -> int: | ||
| try: | ||
| return int(value) if value else 0 | ||
| except ValueError: | ||
| return 0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| from collections.abc import Mapping | ||
| from dataclasses import dataclass | ||
| from typing import Final | ||
|
|
||
| from litellm.tracing.types import SpanRow | ||
|
|
||
| _LLM_OPERATIONS: Final = frozenset({"chat", "text_completion", "generate_content"}) | ||
|
|
||
|
|
||
| @dataclass(frozen=True, slots=True) | ||
| class GenAISemconvNormalizer: | ||
| """OTEL `gen_ai.*` semantic conventions. Matches every span, so it belongs last as the fallback.""" | ||
|
|
||
| name: str = "genai" | ||
|
|
||
| def matches(self, scope_name: str, attributes: Mapping[str, str]) -> bool: | ||
| return True | ||
|
|
||
| def normalize(self, row: SpanRow, attributes: Mapping[str, str]) -> None: | ||
| operation: Final = attributes.get("gen_ai.operation.name", "") | ||
| if operation == "invoke_agent" or not row["ParentSpanId"]: | ||
| row["ObservationType"] = "agent" | ||
| elif operation in _LLM_OPERATIONS: | ||
| row["ObservationType"] = "llm" | ||
| elif operation == "execute_tool": | ||
| row["ObservationType"] = "tool" | ||
| row["AgentName"] = attributes.get("gen_ai.agent.name", "") | ||
| row["Model"] = attributes.get("gen_ai.request.model") or attributes.get("gen_ai.response.model", "") | ||
|
Comment on lines
+25
to
+28
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Context Used: AGENTS.md (source) Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! |
||
| row["LiteLLMRequestId"] = attributes.get("gen_ai.response.id", "") | ||
| row["Input"] = attributes.get("gen_ai.input.messages") or attributes.get("gen_ai.tool.call.arguments", "") | ||
| row["Output"] = attributes.get("gen_ai.output.messages") or attributes.get("gen_ai.tool.call.result", "") | ||
Uh oh!
There was an error while loading. Please reload this page.