opentelemetry-instrumentation-llamaindex 0.33.5__tar.gz → 0.33.6__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.
Potentially problematic release.
This version of opentelemetry-instrumentation-llamaindex might be problematic. Click here for more details.
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/PKG-INFO +1 -1
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/dispatcher_wrapper.py +132 -46
- opentelemetry_instrumentation_llamaindex-0.33.6/opentelemetry/instrumentation/llamaindex/version.py +1 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/pyproject.toml +12 -11
- opentelemetry_instrumentation_llamaindex-0.33.5/opentelemetry/instrumentation/llamaindex/version.py +0 -1
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/README.md +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/__init__.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/base_agent_instrumentor.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/base_embedding_instrumentor.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/base_retriever_instrumentor.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/base_synthesizer_instrumentor.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/base_tool_instrumentor.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/config.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/custom_llm_instrumentor.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/query_pipeline_instrumentor.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/retriever_query_engine_instrumentor.py +0 -0
- {opentelemetry_instrumentation_llamaindex-0.33.5 → opentelemetry_instrumentation_llamaindex-0.33.6}/opentelemetry/instrumentation/llamaindex/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: opentelemetry-instrumentation-llamaindex
|
|
3
|
-
Version: 0.33.
|
|
3
|
+
Version: 0.33.6
|
|
4
4
|
Summary: OpenTelemetry LlamaIndex instrumentation
|
|
5
5
|
Home-page: https://github.com/traceloop/openllmetry/tree/main/packages/opentelemetry-instrumentation-llamaindex
|
|
6
6
|
License: Apache-2.0
|
|
@@ -1,18 +1,24 @@
|
|
|
1
|
+
from functools import singledispatchmethod
|
|
1
2
|
import inspect
|
|
2
3
|
import json
|
|
3
4
|
import re
|
|
4
|
-
from typing import Any, Dict, Optional
|
|
5
|
-
from dataclasses import dataclass
|
|
5
|
+
from typing import Any, AsyncGenerator, Dict, Generator, List, Optional
|
|
6
|
+
from dataclasses import dataclass, field
|
|
6
7
|
|
|
7
8
|
from llama_index.core.bridge.pydantic import PrivateAttr
|
|
8
9
|
from llama_index.core.base.llms.types import MessageRole
|
|
10
|
+
from llama_index.core.base.response.schema import StreamingResponse
|
|
9
11
|
from llama_index.core.instrumentation import get_dispatcher
|
|
10
12
|
from llama_index.core.instrumentation.events import BaseEvent
|
|
11
13
|
from llama_index.core.instrumentation.events.agent import AgentToolCallEvent
|
|
12
14
|
from llama_index.core.instrumentation.events.embedding import EmbeddingStartEvent
|
|
15
|
+
from llama_index.core.instrumentation.events.chat_engine import (
|
|
16
|
+
StreamChatEndEvent,
|
|
17
|
+
)
|
|
13
18
|
from llama_index.core.instrumentation.events.llm import (
|
|
14
19
|
LLMChatEndEvent,
|
|
15
20
|
LLMChatStartEvent,
|
|
21
|
+
LLMCompletionEndEvent,
|
|
16
22
|
LLMPredictEndEvent,
|
|
17
23
|
)
|
|
18
24
|
from llama_index.core.instrumentation.events.rerank import ReRankStartEvent
|
|
@@ -30,18 +36,27 @@ from opentelemetry.semconv_ai import (
|
|
|
30
36
|
SpanAttributes,
|
|
31
37
|
TraceloopSpanKindValues,
|
|
32
38
|
)
|
|
33
|
-
from opentelemetry.trace import
|
|
39
|
+
from opentelemetry.trace import set_span_in_context, Tracer
|
|
34
40
|
from opentelemetry.trace.span import Span
|
|
35
41
|
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
# For these spans, instead of creating a span using data from LlamaIndex,
|
|
44
|
+
# we use the regular OpenLLMetry instrumentations
|
|
45
|
+
AVAILABLE_OPENLLMETRY_INSTRUMENTATIONS = ["OpenAI"]
|
|
46
|
+
|
|
47
|
+
CLASS_NAME_FROM_ID_REGEX = re.compile(r"^([a-zA-Z]+)\.")
|
|
48
|
+
STREAMING_END_EVENTS = (
|
|
49
|
+
LLMChatEndEvent,
|
|
50
|
+
LLMCompletionEndEvent,
|
|
51
|
+
StreamChatEndEvent,
|
|
52
|
+
)
|
|
38
53
|
|
|
39
54
|
|
|
40
55
|
def instrument_with_dispatcher(tracer: Tracer):
|
|
41
56
|
dispatcher = get_dispatcher()
|
|
42
|
-
|
|
43
|
-
dispatcher.add_span_handler(
|
|
44
|
-
dispatcher.add_event_handler(
|
|
57
|
+
openllmetry_span_handler = OpenLLMetrySpanHandler(tracer)
|
|
58
|
+
dispatcher.add_span_handler(openllmetry_span_handler)
|
|
59
|
+
dispatcher.add_event_handler(OpenLLMetryEventHandler(openllmetry_span_handler))
|
|
45
60
|
|
|
46
61
|
|
|
47
62
|
@dont_throw
|
|
@@ -85,18 +100,16 @@ def _set_llm_chat_response(event, span) -> None:
|
|
|
85
100
|
return
|
|
86
101
|
span.set_attribute(
|
|
87
102
|
SpanAttributes.LLM_RESPONSE_MODEL,
|
|
88
|
-
|
|
103
|
+
(
|
|
104
|
+
raw.get("model") if "model" in raw else raw.model
|
|
105
|
+
), # raw can be Any, not just ChatCompletion
|
|
89
106
|
)
|
|
90
107
|
if usage := raw.get("usage") if "usage" in raw else raw.usage:
|
|
91
108
|
span.set_attribute(
|
|
92
109
|
SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, usage.completion_tokens
|
|
93
110
|
)
|
|
94
|
-
span.set_attribute(
|
|
95
|
-
|
|
96
|
-
)
|
|
97
|
-
span.set_attribute(
|
|
98
|
-
SpanAttributes.LLM_USAGE_TOTAL_TOKENS, usage.total_tokens
|
|
99
|
-
)
|
|
111
|
+
span.set_attribute(SpanAttributes.LLM_USAGE_PROMPT_TOKENS, usage.prompt_tokens)
|
|
112
|
+
span.set_attribute(SpanAttributes.LLM_USAGE_TOTAL_TOKENS, usage.total_tokens)
|
|
100
113
|
if choices := raw.choices:
|
|
101
114
|
span.set_attribute(
|
|
102
115
|
SpanAttributes.LLM_RESPONSE_FINISH_REASON, choices[0].finish_reason
|
|
@@ -151,12 +164,71 @@ def _set_tool(event, span) -> None:
|
|
|
151
164
|
|
|
152
165
|
@dataclass
|
|
153
166
|
class SpanHolder:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
167
|
+
span_id: str
|
|
168
|
+
parent: Optional["SpanHolder"] = None
|
|
169
|
+
otel_span: Optional[Span] = None
|
|
170
|
+
token: Optional[Any] = None
|
|
171
|
+
context: Optional[context_api.context.Context] = None
|
|
172
|
+
waiting_for_streaming: bool = field(init=False, default=False)
|
|
173
|
+
|
|
174
|
+
_active: bool = field(init=False, default=True)
|
|
175
|
+
|
|
176
|
+
def process_event(self, event: BaseEvent) -> List["SpanHolder"]:
|
|
177
|
+
self.update_span_for_event(event)
|
|
178
|
+
|
|
179
|
+
if self.waiting_for_streaming and isinstance(event, STREAMING_END_EVENTS):
|
|
180
|
+
self.end()
|
|
181
|
+
return [self] + self.notify_parent()
|
|
182
|
+
|
|
183
|
+
return []
|
|
184
|
+
|
|
185
|
+
def notify_parent(self) -> List["SpanHolder"]:
|
|
186
|
+
if self.parent:
|
|
187
|
+
self.parent.end()
|
|
188
|
+
return [self.parent] + self.parent.notify_parent()
|
|
189
|
+
return []
|
|
190
|
+
|
|
191
|
+
def end(self):
|
|
192
|
+
if not self._active:
|
|
193
|
+
return
|
|
194
|
+
|
|
195
|
+
self._active = False
|
|
196
|
+
if self.otel_span:
|
|
197
|
+
self.otel_span.end()
|
|
198
|
+
if self.token:
|
|
199
|
+
context_api.detach(self.token)
|
|
200
|
+
|
|
201
|
+
@singledispatchmethod
|
|
202
|
+
def update_span_for_event(self, event: BaseEvent):
|
|
203
|
+
pass
|
|
204
|
+
|
|
205
|
+
@update_span_for_event.register
|
|
206
|
+
def _(self, event: LLMChatStartEvent):
|
|
207
|
+
_set_llm_chat_request(event, self.otel_span)
|
|
157
208
|
|
|
209
|
+
@update_span_for_event.register
|
|
210
|
+
def _(self, event: LLMChatEndEvent):
|
|
211
|
+
_set_llm_chat_response(event, self.otel_span)
|
|
158
212
|
|
|
159
|
-
|
|
213
|
+
@update_span_for_event.register
|
|
214
|
+
def _(self, event: LLMPredictEndEvent):
|
|
215
|
+
_set_llm_predict_response(event, self.otel_span)
|
|
216
|
+
|
|
217
|
+
@update_span_for_event.register
|
|
218
|
+
def _(self, event: EmbeddingStartEvent):
|
|
219
|
+
_set_embedding(event, self.otel_span)
|
|
220
|
+
|
|
221
|
+
@update_span_for_event.register
|
|
222
|
+
def _(self, event: ReRankStartEvent):
|
|
223
|
+
_set_rerank(event, self.otel_span)
|
|
224
|
+
|
|
225
|
+
@update_span_for_event.register
|
|
226
|
+
def _(self, event: AgentToolCallEvent):
|
|
227
|
+
_set_tool(event, self.otel_span)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class OpenLLMetrySpanHandler(BaseSpanHandler[SpanHolder]):
|
|
231
|
+
waiting_for_streaming_spans: Dict[str, SpanHolder] = {}
|
|
160
232
|
_tracer: Tracer = PrivateAttr()
|
|
161
233
|
|
|
162
234
|
def __init__(self, tracer: Tracer):
|
|
@@ -181,7 +253,15 @@ class OpenLLSpanHandler(BaseSpanHandler[SpanHolder]):
|
|
|
181
253
|
)
|
|
182
254
|
# Take the class name from id_ where id_ is e.g.
|
|
183
255
|
# 'SentenceSplitter.split_text_metadata_aware-a2f2a780-2fa6-4682-a88e-80dc1f1ebe6a'
|
|
184
|
-
class_name =
|
|
256
|
+
class_name = CLASS_NAME_FROM_ID_REGEX.match(id_).groups()[0]
|
|
257
|
+
if class_name in AVAILABLE_OPENLLMETRY_INSTRUMENTATIONS:
|
|
258
|
+
context_api.attach(
|
|
259
|
+
context_api.set_value(
|
|
260
|
+
SUPPRESS_LANGUAGE_MODEL_INSTRUMENTATION_KEY, False
|
|
261
|
+
)
|
|
262
|
+
)
|
|
263
|
+
return SpanHolder(id_, parent)
|
|
264
|
+
|
|
185
265
|
span_name = f"{class_name}.{kind}"
|
|
186
266
|
span = self._tracer.start_span(
|
|
187
267
|
span_name,
|
|
@@ -196,21 +276,26 @@ class OpenLLSpanHandler(BaseSpanHandler[SpanHolder]):
|
|
|
196
276
|
current_context,
|
|
197
277
|
)
|
|
198
278
|
token = context_api.attach(current_context)
|
|
279
|
+
|
|
199
280
|
span.set_attribute(SpanAttributes.TRACELOOP_SPAN_KIND, kind)
|
|
200
281
|
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, span_name)
|
|
201
282
|
try:
|
|
202
283
|
if should_send_prompts():
|
|
203
284
|
span.set_attribute(
|
|
204
285
|
SpanAttributes.TRACELOOP_ENTITY_INPUT,
|
|
205
|
-
json.dumps(bound_args.arguments, cls=JSONEncoder)
|
|
286
|
+
json.dumps(bound_args.arguments, cls=JSONEncoder),
|
|
206
287
|
)
|
|
207
288
|
except Exception:
|
|
208
289
|
pass
|
|
209
290
|
|
|
210
|
-
return SpanHolder(span, token, current_context)
|
|
291
|
+
return SpanHolder(id_, parent, span, token, current_context)
|
|
211
292
|
|
|
212
293
|
def prepare_to_exit_span(
|
|
213
|
-
self,
|
|
294
|
+
self,
|
|
295
|
+
id_: str,
|
|
296
|
+
instance: Optional[Any] = None,
|
|
297
|
+
result: Optional[Any] = None,
|
|
298
|
+
**kwargs,
|
|
214
299
|
) -> SpanHolder:
|
|
215
300
|
"""Logic for preparing to drop a span."""
|
|
216
301
|
span_holder = self.open_spans[id_]
|
|
@@ -223,18 +308,22 @@ class OpenLLSpanHandler(BaseSpanHandler[SpanHolder]):
|
|
|
223
308
|
if "source_nodes" in output:
|
|
224
309
|
del output["source_nodes"]
|
|
225
310
|
if should_send_prompts():
|
|
226
|
-
span_holder.
|
|
311
|
+
span_holder.otel_span.set_attribute(
|
|
227
312
|
SpanAttributes.TRACELOOP_ENTITY_OUTPUT,
|
|
228
313
|
json.dumps(output, cls=JSONEncoder),
|
|
229
314
|
)
|
|
230
315
|
except Exception:
|
|
231
316
|
pass
|
|
232
317
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
self.
|
|
237
|
-
|
|
318
|
+
if isinstance(result, (Generator, AsyncGenerator, StreamingResponse)):
|
|
319
|
+
# This is a streaming response, we want to wait for the streaming end event before ending the span
|
|
320
|
+
span_holder.waiting_for_streaming = True
|
|
321
|
+
with self.lock:
|
|
322
|
+
self.waiting_for_streaming_spans[id_] = span_holder
|
|
323
|
+
return span_holder
|
|
324
|
+
else:
|
|
325
|
+
span_holder.end()
|
|
326
|
+
return span_holder
|
|
238
327
|
|
|
239
328
|
def prepare_to_drop_span(
|
|
240
329
|
self, id_: str, err: Optional[Exception], **kwargs
|
|
@@ -243,30 +332,27 @@ class OpenLLSpanHandler(BaseSpanHandler[SpanHolder]):
|
|
|
243
332
|
if id_ in self.open_spans:
|
|
244
333
|
with self.lock:
|
|
245
334
|
span_holder = self.open_spans[id_]
|
|
246
|
-
self.dropped_spans += [span_holder]
|
|
247
335
|
return span_holder
|
|
248
336
|
return None
|
|
249
337
|
|
|
250
338
|
|
|
251
|
-
class
|
|
252
|
-
_span_handler:
|
|
339
|
+
class OpenLLMetryEventHandler(BaseEventHandler):
|
|
340
|
+
_span_handler: OpenLLMetrySpanHandler = PrivateAttr()
|
|
253
341
|
|
|
254
|
-
def __init__(self, span_handler:
|
|
342
|
+
def __init__(self, span_handler: OpenLLMetrySpanHandler):
|
|
255
343
|
super().__init__()
|
|
256
344
|
self._span_handler = span_handler
|
|
257
345
|
|
|
258
346
|
def handle(self, event: BaseEvent, **kwargs) -> Any:
|
|
259
|
-
span =
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
elif isinstance(event, AgentToolCallEvent):
|
|
272
|
-
_set_tool(event, span)
|
|
347
|
+
span = self._span_handler.open_spans.get(event.span_id)
|
|
348
|
+
if not span:
|
|
349
|
+
span = self._span_handler.waiting_for_streaming_spans.get(event.span_id)
|
|
350
|
+
if not span:
|
|
351
|
+
print(f"No span found for event {event}")
|
|
352
|
+
return
|
|
353
|
+
|
|
354
|
+
finished_spans = span.process_event(event)
|
|
355
|
+
|
|
356
|
+
with self._span_handler.lock:
|
|
357
|
+
for span in finished_spans:
|
|
358
|
+
self._span_handler.waiting_for_streaming_spans.pop(span.span_id)
|
opentelemetry_instrumentation_llamaindex-0.33.6/opentelemetry/instrumentation/llamaindex/version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.33.6"
|
|
@@ -8,7 +8,7 @@ show_missing = true
|
|
|
8
8
|
|
|
9
9
|
[tool.poetry]
|
|
10
10
|
name = "opentelemetry-instrumentation-llamaindex"
|
|
11
|
-
version = "0.33.
|
|
11
|
+
version = "0.33.6"
|
|
12
12
|
description = "OpenTelemetry LlamaIndex instrumentation"
|
|
13
13
|
authors = [
|
|
14
14
|
"Gal Kleinman <gal@traceloop.com>",
|
|
@@ -38,18 +38,19 @@ flake8 = "7.0.0"
|
|
|
38
38
|
vcrpy = "^6.0.1"
|
|
39
39
|
pytest-recording = "^0.13.1"
|
|
40
40
|
pytest-asyncio = "^0.23.7"
|
|
41
|
-
chromadb = "
|
|
42
|
-
openai = "^1.
|
|
41
|
+
chromadb = "=0.5.15"
|
|
42
|
+
openai = "^1.52.2"
|
|
43
43
|
opentelemetry-sdk = "^1.27.0"
|
|
44
|
-
llama-index = "^0.
|
|
45
|
-
llama-index-postprocessor-cohere-rerank = "^0.1
|
|
46
|
-
opentelemetry-instrumentation-openai = "==0.33.
|
|
47
|
-
opentelemetry-instrumentation-cohere = "==0.33.
|
|
48
|
-
opentelemetry-instrumentation-chromadb = "==0.33.
|
|
44
|
+
llama-index = "^0.11.20"
|
|
45
|
+
llama-index-postprocessor-cohere-rerank = "^0.2.1"
|
|
46
|
+
opentelemetry-instrumentation-openai = "==0.33.6"
|
|
47
|
+
opentelemetry-instrumentation-cohere = "==0.33.6"
|
|
48
|
+
opentelemetry-instrumentation-chromadb = "==0.33.6"
|
|
49
49
|
sqlalchemy = "^2.0.31"
|
|
50
|
-
llama-index-agent-openai = "
|
|
51
|
-
llama-index-vector-stores-chroma = "^0.1
|
|
52
|
-
llama-index-llms-cohere = "^0.2
|
|
50
|
+
llama-index-agent-openai = "^0.3.4"
|
|
51
|
+
llama-index-vector-stores-chroma = "^0.2.1"
|
|
52
|
+
llama-index-llms-cohere = "^0.3.2"
|
|
53
|
+
llama-index-embeddings-openai = "^0.2.5"
|
|
53
54
|
|
|
54
55
|
[build-system]
|
|
55
56
|
requires = ["poetry-core"]
|
opentelemetry_instrumentation_llamaindex-0.33.5/opentelemetry/instrumentation/llamaindex/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.33.5"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|