arize-phoenix 10.1.0__py3-none-any.whl → 10.2.1__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-10.1.0.dist-info → arize_phoenix-10.2.1.dist-info}/METADATA +2 -2
- {arize_phoenix-10.1.0.dist-info → arize_phoenix-10.2.1.dist-info}/RECORD +19 -19
- phoenix/db/insertion/dataset.py +2 -1
- phoenix/db/types/model_provider.py +1 -0
- phoenix/server/api/helpers/playground_clients.py +29 -0
- phoenix/server/api/helpers/prompts/models.py +20 -0
- phoenix/server/api/routers/v1/datasets.py +8 -2
- phoenix/server/api/types/GenerativeProvider.py +5 -0
- phoenix/server/static/.vite/manifest.json +9 -9
- phoenix/server/static/assets/{components-BHJEWQsc.js → components-ClD3sHta.js} +164 -164
- phoenix/server/static/assets/{index-CAt4FOOX.js → index-CXawXHw0.js} +1 -1
- phoenix/server/static/assets/{pages-kpw8RDmo.js → pages-BFtNRfTL.js} +122 -122
- phoenix/session/evaluation.py +6 -1
- phoenix/trace/dsl/helpers.py +90 -1
- phoenix/version.py +1 -1
- {arize_phoenix-10.1.0.dist-info → arize_phoenix-10.2.1.dist-info}/WHEEL +0 -0
- {arize_phoenix-10.1.0.dist-info → arize_phoenix-10.2.1.dist-info}/entry_points.txt +0 -0
- {arize_phoenix-10.1.0.dist-info → arize_phoenix-10.2.1.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-10.1.0.dist-info → arize_phoenix-10.2.1.dist-info}/licenses/LICENSE +0 -0
phoenix/session/evaluation.py
CHANGED
|
@@ -23,13 +23,18 @@ from google.protobuf.wrappers_pb2 import DoubleValue, StringValue
|
|
|
23
23
|
import phoenix.trace.v1 as pb
|
|
24
24
|
from phoenix.config import get_env_collector_endpoint, get_env_host, get_env_port
|
|
25
25
|
from phoenix.session.client import Client
|
|
26
|
-
from phoenix.trace.dsl.helpers import
|
|
26
|
+
from phoenix.trace.dsl.helpers import (
|
|
27
|
+
get_called_tools,
|
|
28
|
+
get_qa_with_reference,
|
|
29
|
+
get_retrieved_documents,
|
|
30
|
+
)
|
|
27
31
|
from phoenix.trace.exporter import HttpExporter
|
|
28
32
|
from phoenix.trace.span_evaluations import Evaluations
|
|
29
33
|
|
|
30
34
|
__all__ = [
|
|
31
35
|
"get_retrieved_documents",
|
|
32
36
|
"get_qa_with_reference",
|
|
37
|
+
"get_called_tools",
|
|
33
38
|
"add_evaluations",
|
|
34
39
|
]
|
|
35
40
|
|
phoenix/trace/dsl/helpers.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import warnings
|
|
2
3
|
from datetime import datetime
|
|
3
|
-
from typing import Optional, Protocol, Union, cast
|
|
4
|
+
from typing import Any, Iterable, Mapping, Optional, Protocol, Union, cast
|
|
4
5
|
|
|
5
6
|
import pandas as pd
|
|
6
7
|
from openinference.semconv.trace import DocumentAttributes, SpanAttributes
|
|
@@ -13,11 +14,16 @@ DOCUMENT_SCORE = DocumentAttributes.DOCUMENT_SCORE
|
|
|
13
14
|
INPUT_VALUE = SpanAttributes.INPUT_VALUE
|
|
14
15
|
OUTPUT_VALUE = SpanAttributes.OUTPUT_VALUE
|
|
15
16
|
RETRIEVAL_DOCUMENTS = SpanAttributes.RETRIEVAL_DOCUMENTS
|
|
17
|
+
LLM_FUNCTION_CALL = SpanAttributes.LLM_FUNCTION_CALL
|
|
18
|
+
LLM_INPUT_MESSAGES = SpanAttributes.LLM_INPUT_MESSAGES
|
|
19
|
+
LLM_OUTPUT_MESSAGES = SpanAttributes.LLM_OUTPUT_MESSAGES
|
|
20
|
+
|
|
16
21
|
|
|
17
22
|
INPUT = {"input": INPUT_VALUE}
|
|
18
23
|
OUTPUT = {"output": OUTPUT_VALUE}
|
|
19
24
|
IO = {**INPUT, **OUTPUT}
|
|
20
25
|
|
|
26
|
+
|
|
21
27
|
IS_ROOT = "parent_id is None"
|
|
22
28
|
IS_LLM = "span_kind == 'LLM'"
|
|
23
29
|
IS_RETRIEVER = "span_kind == 'RETRIEVER'"
|
|
@@ -125,3 +131,86 @@ def get_qa_with_reference(
|
|
|
125
131
|
df_ref = pd.DataFrame({"reference": ref})
|
|
126
132
|
df_qa_ref = pd.concat([df_qa, df_ref], axis=1, join="inner").set_index("context.span_id")
|
|
127
133
|
return df_qa_ref
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def get_called_tools(
|
|
137
|
+
obj: CanQuerySpans,
|
|
138
|
+
*,
|
|
139
|
+
start_time: Optional[datetime] = None,
|
|
140
|
+
end_time: Optional[datetime] = None,
|
|
141
|
+
project_name: Optional[str] = None,
|
|
142
|
+
timeout: Optional[int] = DEFAULT_TIMEOUT_IN_SECONDS,
|
|
143
|
+
function_name_only: bool = False,
|
|
144
|
+
) -> Optional[pd.DataFrame]:
|
|
145
|
+
"""Retrieve tool calls made by LLM spans within a specified time range.
|
|
146
|
+
|
|
147
|
+
This function queries LLM spans and extracts tool calls from their output messages.
|
|
148
|
+
It can return either just the function names or full function calls with arguments.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
obj: An object that implements the CanQuerySpans protocol for querying spans.
|
|
152
|
+
start_time: Optional start time to filter spans. If None, no start time filter is applied.
|
|
153
|
+
end_time: Optional end time to filter spans. If None, no end time filter is applied.
|
|
154
|
+
project_name: Optional project name to filter spans. If None, uses the environment project name.
|
|
155
|
+
timeout: Optional timeout in seconds for the query. Defaults to DEFAULT_TIMEOUT_IN_SECONDS.
|
|
156
|
+
function_name_only: If True, returns only function names. If False, returns full function calls
|
|
157
|
+
with arguments. Defaults to False.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
A pandas DataFrame containing the tool calls, or None if no spans are found.
|
|
161
|
+
The DataFrame includes columns for input messages, output messages, and tool calls.
|
|
162
|
+
""" # noqa: E501
|
|
163
|
+
project_name = project_name or get_env_project_name()
|
|
164
|
+
|
|
165
|
+
def extract_tool_calls(outputs: list[dict[str, Any]]) -> Optional[list[str]]:
|
|
166
|
+
if not isinstance(outputs, list) or not outputs:
|
|
167
|
+
return None
|
|
168
|
+
ans = []
|
|
169
|
+
if isinstance(message := outputs[0].get("message"), Mapping) and isinstance(
|
|
170
|
+
tool_calls := message.get("tool_calls"), Iterable
|
|
171
|
+
):
|
|
172
|
+
for tool_call in tool_calls:
|
|
173
|
+
if not isinstance(tool_call, Mapping):
|
|
174
|
+
continue
|
|
175
|
+
if not isinstance(tc := tool_call.get("tool_call"), Mapping):
|
|
176
|
+
continue
|
|
177
|
+
if not isinstance(function := tc.get("function"), Mapping):
|
|
178
|
+
continue
|
|
179
|
+
if not isinstance(name := function.get("name"), str):
|
|
180
|
+
continue
|
|
181
|
+
if function_name_only:
|
|
182
|
+
ans.append(name)
|
|
183
|
+
continue
|
|
184
|
+
kwargs = {}
|
|
185
|
+
if isinstance(arguments := function.get("arguments"), str):
|
|
186
|
+
try:
|
|
187
|
+
kwargs = json.loads(arguments)
|
|
188
|
+
except Exception:
|
|
189
|
+
pass
|
|
190
|
+
kwargs_str = "" if not kwargs else ", ".join(f"{k}={v}" for k, v in kwargs.items())
|
|
191
|
+
ans.append(f"{name}({kwargs_str})")
|
|
192
|
+
return ans or None
|
|
193
|
+
|
|
194
|
+
df_qa = cast(
|
|
195
|
+
pd.DataFrame,
|
|
196
|
+
obj.query_spans(
|
|
197
|
+
SpanQuery()
|
|
198
|
+
.where(IS_LLM)
|
|
199
|
+
.select(
|
|
200
|
+
input=LLM_INPUT_MESSAGES,
|
|
201
|
+
output=LLM_OUTPUT_MESSAGES,
|
|
202
|
+
),
|
|
203
|
+
start_time=start_time,
|
|
204
|
+
end_time=end_time,
|
|
205
|
+
project_name=project_name,
|
|
206
|
+
timeout=timeout,
|
|
207
|
+
),
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
if df_qa is None:
|
|
211
|
+
print("No spans found.")
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
df_qa["tool_call"] = df_qa["output"].apply(extract_tool_calls)
|
|
215
|
+
|
|
216
|
+
return df_qa
|
phoenix/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "10.1
|
|
1
|
+
__version__ = "10.2.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|