arize-phoenix 0.0.39__py3-none-any.whl → 0.0.41__py3-none-any.whl
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 arize-phoenix might be problematic. Click here for more details.
- {arize_phoenix-0.0.39.dist-info → arize_phoenix-0.0.41.dist-info}/METADATA +13 -12
- {arize_phoenix-0.0.39.dist-info → arize_phoenix-0.0.41.dist-info}/RECORD +14 -13
- phoenix/__init__.py +1 -1
- phoenix/core/traces.py +1 -1
- phoenix/experimental/evals/functions/binary.py +8 -0
- phoenix/experimental/evals/retrievals.py +3 -1
- phoenix/server/static/index.js +357 -357
- phoenix/trace/fixtures.py +9 -2
- phoenix/trace/langchain/__init__.py +2 -1
- phoenix/trace/langchain/instrumentor.py +37 -0
- phoenix/trace/llama_index/callback.py +26 -11
- {arize_phoenix-0.0.39.dist-info → arize_phoenix-0.0.41.dist-info}/WHEEL +0 -0
- {arize_phoenix-0.0.39.dist-info → arize_phoenix-0.0.41.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-0.0.39.dist-info → arize_phoenix-0.0.41.dist-info}/licenses/LICENSE +0 -0
phoenix/trace/fixtures.py
CHANGED
|
@@ -19,7 +19,7 @@ llama_index_rag_fixture = TracesFixture(
|
|
|
19
19
|
file_name="llama_index_rag_v6.jsonl",
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
llama_index_calculator_agent_fixture = TracesFixture(
|
|
23
23
|
name="llama_index_calculator_agent",
|
|
24
24
|
description="Traces from running the llama_index with calculator tools.",
|
|
25
25
|
file_name="llama_index_calculator_agent_v2.jsonl",
|
|
@@ -43,6 +43,12 @@ langchain_titanic_csv_agent_evaluator_fixture = TracesFixture(
|
|
|
43
43
|
file_name="lc_titanic.jsonl",
|
|
44
44
|
)
|
|
45
45
|
|
|
46
|
+
langchain_qa_with_sources_fixture = TracesFixture(
|
|
47
|
+
name="langchain_qa_with_sources",
|
|
48
|
+
description="LangChain QA with sources on financial data",
|
|
49
|
+
file_name="langchain_qa_with_sources_chain.jsonl",
|
|
50
|
+
)
|
|
51
|
+
|
|
46
52
|
random_fixture = TracesFixture(
|
|
47
53
|
name="random",
|
|
48
54
|
description="Randomly generated traces",
|
|
@@ -55,7 +61,8 @@ TRACES_FIXTURES: List[TracesFixture] = [
|
|
|
55
61
|
langchain_rag_stuff_document_chain_fixture,
|
|
56
62
|
langchain_titanic_csv_agent_evaluator_fixture,
|
|
57
63
|
random_fixture,
|
|
58
|
-
|
|
64
|
+
langchain_qa_with_sources_fixture,
|
|
65
|
+
llama_index_calculator_agent_fixture,
|
|
59
66
|
]
|
|
60
67
|
|
|
61
68
|
NAME_TO_TRACES_FIXTURE = {fixture.name: fixture for fixture in TRACES_FIXTURES}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
2
|
+
|
|
3
|
+
from .tracer import OpenInferenceTracer
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LangChainInstrumentor:
|
|
7
|
+
"""
|
|
8
|
+
Instruments the OpenInferenceTracer for LangChain automatically by patching the
|
|
9
|
+
BaseCallbackManager in LangChain.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, tracer: Optional[OpenInferenceTracer] = None) -> None:
|
|
13
|
+
self._tracer = tracer if tracer is not None else OpenInferenceTracer()
|
|
14
|
+
|
|
15
|
+
def instrument(self) -> None:
|
|
16
|
+
try:
|
|
17
|
+
from langchain.callbacks.base import BaseCallbackManager
|
|
18
|
+
except ImportError:
|
|
19
|
+
# Raise a cleaner error if LangChain is not installed
|
|
20
|
+
raise ImportError(
|
|
21
|
+
"LangChain is not installed. Please install LangChain first to use the instrumentor"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
source_init = BaseCallbackManager.__init__
|
|
25
|
+
|
|
26
|
+
# Keep track of the source init so we can tell if the patching occurred
|
|
27
|
+
self._source_callback_manager_init = source_init
|
|
28
|
+
|
|
29
|
+
tracer = self._tracer
|
|
30
|
+
|
|
31
|
+
# Patch the init method of the BaseCallbackManager to add the tracer
|
|
32
|
+
# to all callback managers
|
|
33
|
+
def patched_init(self: BaseCallbackManager, *args: Any, **kwargs: Any) -> None:
|
|
34
|
+
source_init(self, *args, **kwargs)
|
|
35
|
+
self.add_handler(tracer, True)
|
|
36
|
+
|
|
37
|
+
BaseCallbackManager.__init__ = patched_init # type: ignore
|
|
@@ -106,14 +106,6 @@ def payload_to_semantic_attributes(
|
|
|
106
106
|
if event_type in (CBEventType.NODE_PARSING, CBEventType.CHUNKING):
|
|
107
107
|
# TODO(maybe): handle these events
|
|
108
108
|
return attributes
|
|
109
|
-
if event_type == CBEventType.TEMPLATING:
|
|
110
|
-
if template := payload.get(EventPayload.TEMPLATE):
|
|
111
|
-
attributes[LLM_PROMPT_TEMPLATE] = template
|
|
112
|
-
if template_vars := payload.get(EventPayload.TEMPLATE_VARS):
|
|
113
|
-
attributes[LLM_PROMPT_TEMPLATE_VARIABLES] = template_vars
|
|
114
|
-
# TODO(maybe): other keys in the same payload
|
|
115
|
-
# EventPayload.SYSTEM_PROMPT
|
|
116
|
-
# EventPayload.QUERY_WRAPPER_PROMPT
|
|
117
109
|
if EventPayload.CHUNKS in payload and EventPayload.EMBEDDINGS in payload:
|
|
118
110
|
attributes[EMBEDDING_EMBEDDINGS] = [
|
|
119
111
|
{EMBEDDING_TEXT: text, EMBEDDING_VECTOR: vector}
|
|
@@ -151,8 +143,6 @@ def payload_to_semantic_attributes(
|
|
|
151
143
|
attributes.update(_get_output_messages(raw))
|
|
152
144
|
if (usage := getattr(raw, "usage", None)) is not None:
|
|
153
145
|
attributes.update(_get_token_counts(usage))
|
|
154
|
-
if EventPayload.TEMPLATE in payload:
|
|
155
|
-
...
|
|
156
146
|
if event_type is CBEventType.RERANKING:
|
|
157
147
|
... # TODO
|
|
158
148
|
# if EventPayload.TOP_K in payload:
|
|
@@ -304,6 +294,20 @@ def _add_spans_to_tracer(
|
|
|
304
294
|
parent_span_id, event_id = parent_child_id_stack.pop()
|
|
305
295
|
event_data = event_id_to_event_data[event_id]
|
|
306
296
|
event_type = event_data["event_type"]
|
|
297
|
+
attributes = event_data["attributes"]
|
|
298
|
+
if event_type is CBEventType.LLM:
|
|
299
|
+
while parent_child_id_stack:
|
|
300
|
+
preceding_event_parent_span_id, preceding_event_id = parent_child_id_stack[-1]
|
|
301
|
+
if preceding_event_parent_span_id != parent_span_id:
|
|
302
|
+
break
|
|
303
|
+
preceding_event_data = event_id_to_event_data[preceding_event_id]
|
|
304
|
+
if preceding_event_data["event_type"] is not CBEventType.TEMPLATING:
|
|
305
|
+
break
|
|
306
|
+
parent_child_id_stack.pop()
|
|
307
|
+
if payload := preceding_event_data["start_event"].payload:
|
|
308
|
+
# Add template attributes to the LLM span to which they belong.
|
|
309
|
+
attributes.update(_template_attributes(payload))
|
|
310
|
+
|
|
307
311
|
start_event = event_data["start_event"]
|
|
308
312
|
start_time = _timestamp_to_tz_aware_datetime(start_event.time)
|
|
309
313
|
if event_type is CBEventType.EXCEPTION:
|
|
@@ -337,7 +341,7 @@ def _add_spans_to_tracer(
|
|
|
337
341
|
status_code=SpanStatusCode.ERROR if span_exceptions else SpanStatusCode.OK,
|
|
338
342
|
status_message="",
|
|
339
343
|
parent_id=parent_span_id,
|
|
340
|
-
attributes=
|
|
344
|
+
attributes=attributes,
|
|
341
345
|
events=sorted(span_exceptions, key=lambda event: event.timestamp) or None,
|
|
342
346
|
conversation=None,
|
|
343
347
|
)
|
|
@@ -490,3 +494,14 @@ def _get_token_counts(usage: object) -> Iterator[Tuple[str, Any]]:
|
|
|
490
494
|
yield LLM_TOKEN_COUNT_COMPLETION, completion_tokens
|
|
491
495
|
if (total_tokens := getattr(usage, "total_tokens", None)) is not None:
|
|
492
496
|
yield LLM_TOKEN_COUNT_TOTAL, total_tokens
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def _template_attributes(payload: Dict[str, Any]) -> Iterator[Tuple[str, Any]]:
|
|
500
|
+
"""Yields template attributes if present"""
|
|
501
|
+
if template := payload.get(EventPayload.TEMPLATE):
|
|
502
|
+
yield LLM_PROMPT_TEMPLATE, template
|
|
503
|
+
if template_vars := payload.get(EventPayload.TEMPLATE_VARS):
|
|
504
|
+
yield LLM_PROMPT_TEMPLATE_VARIABLES, template_vars
|
|
505
|
+
# TODO(maybe): other keys in the same payload
|
|
506
|
+
# EventPayload.SYSTEM_PROMPT
|
|
507
|
+
# EventPayload.QUERY_WRAPPER_PROMPT
|
|
File without changes
|
|
File without changes
|
|
File without changes
|