agento11y-litellm 0.10.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ SPDX-License-Identifier: Apache-2.0
2
+
3
+ See /sdks/LICENSE at repository root for full license text.
@@ -0,0 +1,195 @@
1
+ Metadata-Version: 2.4
2
+ Name: agento11y-litellm
3
+ Version: 0.10.0
4
+ Summary: LiteLLM callback handler for the Grafana Agent Observability Python SDK
5
+ License: SPDX-License-Identifier: Apache-2.0
6
+
7
+ See /sdks/LICENSE at repository root for full license text.
8
+
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: aiohttp>=3.14.1
13
+ Requires-Dist: agento11y>=0.10.0
14
+ Requires-Dist: litellm!=1.82.7,!=1.82.8,>=1.82.3
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=8.2.0; extra == "dev"
17
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
18
+ Dynamic: license-file
19
+
20
+ # Sigil Python Framework Module: LiteLLM
21
+
22
+ `agento11y-litellm` is a LiteLLM callback handler that exports generation telemetry to Sigil.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install agento11y agento11y-litellm
28
+ pip install litellm
29
+ ```
30
+
31
+ ## Quickstart
32
+
33
+ ```python
34
+ import litellm
35
+ from agento11y import Client
36
+ from agento11y_litellm import Agento11yLiteLLMLogger
37
+
38
+ client = Client()
39
+ handler = Agento11yLiteLLMLogger(client=client)
40
+
41
+ litellm.callbacks = [handler]
42
+
43
+ response = litellm.completion(
44
+ model="openai/gpt-4o-mini",
45
+ messages=[{"role": "user", "content": "Hello!"}],
46
+ )
47
+ print(response.choices[0].message.content)
48
+
49
+ client.shutdown()
50
+ ```
51
+
52
+ ## Streaming
53
+
54
+ ```python
55
+ import litellm
56
+ from agento11y import Client
57
+ from agento11y_litellm import Agento11yLiteLLMLogger
58
+
59
+ client = Client()
60
+ litellm.callbacks = [Agento11yLiteLLMLogger(client=client)]
61
+
62
+ response = litellm.completion(
63
+ model="openai/gpt-4o-mini",
64
+ messages=[{"role": "user", "content": "Give me three reliability tips."}],
65
+ stream=True,
66
+ )
67
+ for chunk in response:
68
+ content = chunk.choices[0].delta.content
69
+ if content:
70
+ print(content, end="", flush=True)
71
+ print()
72
+
73
+ client.shutdown()
74
+ ```
75
+
76
+ ## Configuration
77
+
78
+ All options are keyword-only on `Agento11yLiteLLMLogger`:
79
+
80
+ | Parameter | Type | Default | Description |
81
+ |---|---|---|---|
82
+ | `client` | `agento11y.Client` | required | Sigil SDK client instance |
83
+ | `capture_inputs` | `bool` | `True` | Record input messages |
84
+ | `capture_outputs` | `bool` | `True` | Record output messages |
85
+ | `agent_name` | `str` | `""` | Default agent name (see below for per-request) |
86
+ | `agent_version` | `str` | `""` | Default agent version (see below for per-request) |
87
+ | `conversation_id` | `str` | `""` | Default conversation ID (see below for per-request) |
88
+ | `extra_tags` | `dict[str, str]` | `None` | Additional tags merged into every generation |
89
+ | `extra_metadata` | `dict[str, Any]` | `None` | Additional metadata merged into every generation |
90
+
91
+ The `create_agento11y_litellm_logger` factory accepts the same parameters.
92
+
93
+ ## Per-Request Metadata
94
+
95
+ The handler resolves `agent_name`, `agent_version`, and `conversation_id` from per-request LiteLLM metadata, falling back to the static values from handler init. This is useful when multiple agents share a single LiteLLM proxy.
96
+
97
+ ```python
98
+ response = litellm.completion(
99
+ model="openai/gpt-4o-mini",
100
+ messages=[{"role": "user", "content": "Continue our chat."}],
101
+ metadata={
102
+ "agent_name": "search-agent",
103
+ "agent_version": "v2",
104
+ "conversation_id": "conv-abc-123",
105
+ },
106
+ )
107
+ ```
108
+
109
+ For `conversation_id`, the handler also checks `session_id` and `thread_id` metadata keys as fallbacks.
110
+
111
+ ## LiteLLM Proxy (Docker)
112
+
113
+ When running LiteLLM as a proxy server in Docker, register the handler via a callback file next to your config.
114
+
115
+ **1. Extend the Docker image:**
116
+
117
+ ```dockerfile
118
+ FROM ghcr.io/berriai/litellm:v1.82.3-stable.patch.2
119
+ RUN pip install agento11y agento11y-litellm
120
+ ```
121
+
122
+ **2. Create a callback file** (`agento11y_callback.py`, same directory as `config.yaml`):
123
+
124
+ ```python
125
+ import os
126
+
127
+ from agento11y import Client
128
+ from agento11y.config import AuthConfig, ClientConfig, GenerationExportConfig
129
+ from agento11y_litellm import Agento11yLiteLLMLogger
130
+
131
+ client = Client(ClientConfig(
132
+ generation_export=GenerationExportConfig(
133
+ protocol="http",
134
+ endpoint=os.environ["AGENTO11Y_ENDPOINT"],
135
+ auth=AuthConfig(
136
+ mode="basic",
137
+ tenant_id=os.environ.get("AGENTO11Y_AUTH_TENANT_ID", ""),
138
+ basic_password=os.environ.get("AGENTO11Y_AUTH_TOKEN", ""),
139
+ ),
140
+ ),
141
+ ))
142
+ agento11y_handler = Agento11yLiteLLMLogger(
143
+ client=client,
144
+ agent_name="litellm-proxy",
145
+ )
146
+ ```
147
+
148
+ **3. Reference it in `config.yaml`:**
149
+
150
+ ```yaml
151
+ model_list:
152
+ - model_name: gpt-4o-mini
153
+ litellm_params:
154
+ model: openai/gpt-4o-mini
155
+
156
+ litellm_settings:
157
+ callbacks: agento11y_callback.agento11y_handler
158
+ ```
159
+
160
+ The proxy resolves `agento11y_callback.agento11y_handler` by importing `agento11y_callback.py` from the config directory and using the `agento11y_handler` instance.
161
+
162
+ **4. Mount both files and run:**
163
+
164
+ ```bash
165
+ docker run -d \
166
+ -v $(pwd)/config.yaml:/app/config.yaml \
167
+ -v $(pwd)/agento11y_callback.py:/app/agento11y_callback.py \
168
+ -e AGENTO11Y_ENDPOINT=https://your-agento11y-endpoint \
169
+ -e AGENTO11Y_AUTH_TENANT_ID=your-tenant \
170
+ -e AGENTO11Y_AUTH_TOKEN=your-key \
171
+ -p 4000:4000 \
172
+ your-litellm-image \
173
+ --config /app/config.yaml
174
+ ```
175
+
176
+ The callback file reads connection details from environment variables. Adjust the `AuthConfig` mode to match your deployment (see `agento11y.config` for `tenant`, `bearer`, and `basic` modes).
177
+
178
+ ## Behavior
179
+
180
+ - Mode mapping: non-stream calls -> `SYNC`, stream calls -> `STREAM` with first-token timestamp.
181
+ - Provider detection: uses `custom_llm_provider` from LiteLLM's standard logging object.
182
+ - Failed calls are recorded with the error attached via `set_call_error`.
183
+ - Chat completion call types (`completion`, `acompletion`, `text_completion`, `atext_completion`) are recorded as generations.
184
+ - Embedding call types (`embedding`, `aembedding`) are recorded as OTel embedding spans (no generation export). The span carries input/token counts and dimensions; the input text is attached only when the handler's `capture_inputs` is set and the SDK's `EmbeddingCaptureConfig.capture_input=True`. Embedding spans require a configured OTel tracer.
185
+ - Image, audio, and transcription call types are skipped.
186
+ - Framework tags are always set:
187
+ - `agento11y.framework.name=litellm`
188
+ - `agento11y.framework.source=handler`
189
+ - `agento11y.framework.language=python`
190
+ - LiteLLM `request_tags` are forwarded as `litellm.tag.<value>`.
191
+ - Token usage includes detailed breakdowns (cached tokens, reasoning tokens) when the provider returns them.
192
+ - Tool calls and tool results in messages are mapped to Sigil's tool call/result parts.
193
+ - Reasoning/thinking text is captured as `THINKING` parts, ordered before the assistant text. It is read from `thinking_blocks` when present (including redacted blocks), otherwise from the flat `reasoning_content` string.
194
+
195
+ Call `client.shutdown()` during teardown to flush buffered telemetry.
@@ -0,0 +1,176 @@
1
+ # Sigil Python Framework Module: LiteLLM
2
+
3
+ `agento11y-litellm` is a LiteLLM callback handler that exports generation telemetry to Sigil.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install agento11y agento11y-litellm
9
+ pip install litellm
10
+ ```
11
+
12
+ ## Quickstart
13
+
14
+ ```python
15
+ import litellm
16
+ from agento11y import Client
17
+ from agento11y_litellm import Agento11yLiteLLMLogger
18
+
19
+ client = Client()
20
+ handler = Agento11yLiteLLMLogger(client=client)
21
+
22
+ litellm.callbacks = [handler]
23
+
24
+ response = litellm.completion(
25
+ model="openai/gpt-4o-mini",
26
+ messages=[{"role": "user", "content": "Hello!"}],
27
+ )
28
+ print(response.choices[0].message.content)
29
+
30
+ client.shutdown()
31
+ ```
32
+
33
+ ## Streaming
34
+
35
+ ```python
36
+ import litellm
37
+ from agento11y import Client
38
+ from agento11y_litellm import Agento11yLiteLLMLogger
39
+
40
+ client = Client()
41
+ litellm.callbacks = [Agento11yLiteLLMLogger(client=client)]
42
+
43
+ response = litellm.completion(
44
+ model="openai/gpt-4o-mini",
45
+ messages=[{"role": "user", "content": "Give me three reliability tips."}],
46
+ stream=True,
47
+ )
48
+ for chunk in response:
49
+ content = chunk.choices[0].delta.content
50
+ if content:
51
+ print(content, end="", flush=True)
52
+ print()
53
+
54
+ client.shutdown()
55
+ ```
56
+
57
+ ## Configuration
58
+
59
+ All options are keyword-only on `Agento11yLiteLLMLogger`:
60
+
61
+ | Parameter | Type | Default | Description |
62
+ |---|---|---|---|
63
+ | `client` | `agento11y.Client` | required | Sigil SDK client instance |
64
+ | `capture_inputs` | `bool` | `True` | Record input messages |
65
+ | `capture_outputs` | `bool` | `True` | Record output messages |
66
+ | `agent_name` | `str` | `""` | Default agent name (see below for per-request) |
67
+ | `agent_version` | `str` | `""` | Default agent version (see below for per-request) |
68
+ | `conversation_id` | `str` | `""` | Default conversation ID (see below for per-request) |
69
+ | `extra_tags` | `dict[str, str]` | `None` | Additional tags merged into every generation |
70
+ | `extra_metadata` | `dict[str, Any]` | `None` | Additional metadata merged into every generation |
71
+
72
+ The `create_agento11y_litellm_logger` factory accepts the same parameters.
73
+
74
+ ## Per-Request Metadata
75
+
76
+ The handler resolves `agent_name`, `agent_version`, and `conversation_id` from per-request LiteLLM metadata, falling back to the static values from handler init. This is useful when multiple agents share a single LiteLLM proxy.
77
+
78
+ ```python
79
+ response = litellm.completion(
80
+ model="openai/gpt-4o-mini",
81
+ messages=[{"role": "user", "content": "Continue our chat."}],
82
+ metadata={
83
+ "agent_name": "search-agent",
84
+ "agent_version": "v2",
85
+ "conversation_id": "conv-abc-123",
86
+ },
87
+ )
88
+ ```
89
+
90
+ For `conversation_id`, the handler also checks `session_id` and `thread_id` metadata keys as fallbacks.
91
+
92
+ ## LiteLLM Proxy (Docker)
93
+
94
+ When running LiteLLM as a proxy server in Docker, register the handler via a callback file next to your config.
95
+
96
+ **1. Extend the Docker image:**
97
+
98
+ ```dockerfile
99
+ FROM ghcr.io/berriai/litellm:v1.82.3-stable.patch.2
100
+ RUN pip install agento11y agento11y-litellm
101
+ ```
102
+
103
+ **2. Create a callback file** (`agento11y_callback.py`, same directory as `config.yaml`):
104
+
105
+ ```python
106
+ import os
107
+
108
+ from agento11y import Client
109
+ from agento11y.config import AuthConfig, ClientConfig, GenerationExportConfig
110
+ from agento11y_litellm import Agento11yLiteLLMLogger
111
+
112
+ client = Client(ClientConfig(
113
+ generation_export=GenerationExportConfig(
114
+ protocol="http",
115
+ endpoint=os.environ["AGENTO11Y_ENDPOINT"],
116
+ auth=AuthConfig(
117
+ mode="basic",
118
+ tenant_id=os.environ.get("AGENTO11Y_AUTH_TENANT_ID", ""),
119
+ basic_password=os.environ.get("AGENTO11Y_AUTH_TOKEN", ""),
120
+ ),
121
+ ),
122
+ ))
123
+ agento11y_handler = Agento11yLiteLLMLogger(
124
+ client=client,
125
+ agent_name="litellm-proxy",
126
+ )
127
+ ```
128
+
129
+ **3. Reference it in `config.yaml`:**
130
+
131
+ ```yaml
132
+ model_list:
133
+ - model_name: gpt-4o-mini
134
+ litellm_params:
135
+ model: openai/gpt-4o-mini
136
+
137
+ litellm_settings:
138
+ callbacks: agento11y_callback.agento11y_handler
139
+ ```
140
+
141
+ The proxy resolves `agento11y_callback.agento11y_handler` by importing `agento11y_callback.py` from the config directory and using the `agento11y_handler` instance.
142
+
143
+ **4. Mount both files and run:**
144
+
145
+ ```bash
146
+ docker run -d \
147
+ -v $(pwd)/config.yaml:/app/config.yaml \
148
+ -v $(pwd)/agento11y_callback.py:/app/agento11y_callback.py \
149
+ -e AGENTO11Y_ENDPOINT=https://your-agento11y-endpoint \
150
+ -e AGENTO11Y_AUTH_TENANT_ID=your-tenant \
151
+ -e AGENTO11Y_AUTH_TOKEN=your-key \
152
+ -p 4000:4000 \
153
+ your-litellm-image \
154
+ --config /app/config.yaml
155
+ ```
156
+
157
+ The callback file reads connection details from environment variables. Adjust the `AuthConfig` mode to match your deployment (see `agento11y.config` for `tenant`, `bearer`, and `basic` modes).
158
+
159
+ ## Behavior
160
+
161
+ - Mode mapping: non-stream calls -> `SYNC`, stream calls -> `STREAM` with first-token timestamp.
162
+ - Provider detection: uses `custom_llm_provider` from LiteLLM's standard logging object.
163
+ - Failed calls are recorded with the error attached via `set_call_error`.
164
+ - Chat completion call types (`completion`, `acompletion`, `text_completion`, `atext_completion`) are recorded as generations.
165
+ - Embedding call types (`embedding`, `aembedding`) are recorded as OTel embedding spans (no generation export). The span carries input/token counts and dimensions; the input text is attached only when the handler's `capture_inputs` is set and the SDK's `EmbeddingCaptureConfig.capture_input=True`. Embedding spans require a configured OTel tracer.
166
+ - Image, audio, and transcription call types are skipped.
167
+ - Framework tags are always set:
168
+ - `agento11y.framework.name=litellm`
169
+ - `agento11y.framework.source=handler`
170
+ - `agento11y.framework.language=python`
171
+ - LiteLLM `request_tags` are forwarded as `litellm.tag.<value>`.
172
+ - Token usage includes detailed breakdowns (cached tokens, reasoning tokens) when the provider returns them.
173
+ - Tool calls and tool results in messages are mapped to Sigil's tool call/result parts.
174
+ - Reasoning/thinking text is captured as `THINKING` parts, ordered before the assistant text. It is read from `thinking_blocks` when present (including redacted blocks), otherwise from the flat `reasoning_content` string.
175
+
176
+ Call `client.shutdown()` during teardown to flush buffered telemetry.
@@ -0,0 +1,37 @@
1
+ """Public exports for Sigil LiteLLM callback handler."""
2
+
3
+ from typing import Any
4
+
5
+ from agento11y import Client
6
+
7
+ from .handler import Agento11yLiteLLMLogger
8
+
9
+
10
+ def create_agento11y_litellm_logger(
11
+ *,
12
+ client: Client,
13
+ capture_inputs: bool = True,
14
+ capture_outputs: bool = True,
15
+ agent_name: str = "",
16
+ agent_version: str = "",
17
+ conversation_id: str = "",
18
+ extra_tags: dict[str, str] | None = None,
19
+ extra_metadata: dict[str, Any] | None = None,
20
+ ) -> Agento11yLiteLLMLogger:
21
+ """Create a LiteLLM Sigil callback logger."""
22
+ return Agento11yLiteLLMLogger(
23
+ client=client,
24
+ capture_inputs=capture_inputs,
25
+ capture_outputs=capture_outputs,
26
+ agent_name=agent_name,
27
+ agent_version=agent_version,
28
+ conversation_id=conversation_id,
29
+ extra_tags=extra_tags,
30
+ extra_metadata=extra_metadata,
31
+ )
32
+
33
+
34
+ __all__ = [
35
+ "Agento11yLiteLLMLogger",
36
+ "create_agento11y_litellm_logger",
37
+ ]