arize-phoenix 11.30.0__py3-none-any.whl → 11.31.0__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-11.30.0.dist-info → arize_phoenix-11.31.0.dist-info}/METADATA +17 -17
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.31.0.dist-info}/RECORD +24 -23
- phoenix/db/types/trace_retention.py +1 -1
- phoenix/server/api/dataloaders/document_evaluations.py +6 -9
- phoenix/server/api/routers/v1/annotations.py +128 -5
- phoenix/server/api/routers/v1/documents.py +47 -79
- phoenix/server/api/routers/v1/spans.py +2 -48
- phoenix/server/api/routers/v1/traces.py +19 -55
- phoenix/server/api/types/Dataset.py +8 -66
- phoenix/server/api/types/DatasetExperimentAnnotationSummary.py +10 -0
- phoenix/server/api/types/DocumentAnnotation.py +92 -0
- phoenix/server/api/types/Span.py +8 -2
- phoenix/server/api/types/TraceAnnotation.py +8 -5
- phoenix/server/cost_tracking/model_cost_manifest.json +91 -0
- phoenix/server/static/.vite/manifest.json +9 -9
- phoenix/server/static/assets/{components-BBwXqJXQ.js → components-BjW5gAwL.js} +1 -1
- phoenix/server/static/assets/{index-C_gU3x10.js → index-3OI8VV_W.js} +1 -1
- phoenix/server/static/assets/{pages-YmQb55Uo.js → pages-CQfUODtD.js} +57 -56
- phoenix/trace/projects.py +6 -0
- phoenix/version.py +1 -1
- phoenix/server/api/types/Evaluation.py +0 -40
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.31.0.dist-info}/WHEEL +0 -0
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.31.0.dist-info}/entry_points.txt +0 -0
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.31.0.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.31.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,7 +5,7 @@ from collections.abc import AsyncIterator
|
|
|
5
5
|
from datetime import datetime, timezone
|
|
6
6
|
from enum import Enum
|
|
7
7
|
from secrets import token_urlsafe
|
|
8
|
-
from typing import Annotated, Any,
|
|
8
|
+
from typing import Annotated, Any, Optional, Union
|
|
9
9
|
|
|
10
10
|
import pandas as pd
|
|
11
11
|
import sqlalchemy as sa
|
|
@@ -27,8 +27,8 @@ from phoenix.datetime_utils import normalize_datetime
|
|
|
27
27
|
from phoenix.db import models
|
|
28
28
|
from phoenix.db.helpers import SupportedSQLDialect, get_ancestor_span_rowids
|
|
29
29
|
from phoenix.db.insertion.helpers import as_kv, insert_on_conflict
|
|
30
|
-
from phoenix.db.insertion.types import Precursors
|
|
31
30
|
from phoenix.server.api.routers.utils import df_to_bytes
|
|
31
|
+
from phoenix.server.api.routers.v1.annotations import SpanAnnotationData
|
|
32
32
|
from phoenix.server.api.types.node import from_global_id_with_expected_type
|
|
33
33
|
from phoenix.server.authorization import is_not_locked
|
|
34
34
|
from phoenix.server.bearer_auth import PhoenixUser
|
|
@@ -850,52 +850,6 @@ async def get_spans_handler(
|
|
|
850
850
|
return await query_spans_handler(request, request_body, project_name)
|
|
851
851
|
|
|
852
852
|
|
|
853
|
-
class SpanAnnotationResult(V1RoutesBaseModel):
|
|
854
|
-
label: Optional[str] = Field(default=None, description="The label assigned by the annotation")
|
|
855
|
-
score: Optional[float] = Field(default=None, description="The score assigned by the annotation")
|
|
856
|
-
explanation: Optional[str] = Field(
|
|
857
|
-
default=None, description="Explanation of the annotation result"
|
|
858
|
-
)
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
class SpanAnnotationData(V1RoutesBaseModel):
|
|
862
|
-
span_id: str = Field(description="OpenTelemetry Span ID (hex format w/o 0x prefix)")
|
|
863
|
-
name: str = Field(description="The name of the annotation")
|
|
864
|
-
annotator_kind: Literal["LLM", "CODE", "HUMAN"] = Field(
|
|
865
|
-
description="The kind of annotator used for the annotation"
|
|
866
|
-
)
|
|
867
|
-
result: Optional[SpanAnnotationResult] = Field(
|
|
868
|
-
default=None, description="The result of the annotation"
|
|
869
|
-
)
|
|
870
|
-
metadata: Optional[dict[str, Any]] = Field(
|
|
871
|
-
default=None, description="Metadata for the annotation"
|
|
872
|
-
)
|
|
873
|
-
identifier: str = Field(
|
|
874
|
-
default="",
|
|
875
|
-
description=(
|
|
876
|
-
"The identifier of the annotation. "
|
|
877
|
-
"If provided, the annotation will be updated if it already exists."
|
|
878
|
-
),
|
|
879
|
-
)
|
|
880
|
-
|
|
881
|
-
def as_precursor(self, *, user_id: Optional[int] = None) -> Precursors.SpanAnnotation:
|
|
882
|
-
return Precursors.SpanAnnotation(
|
|
883
|
-
datetime.now(timezone.utc),
|
|
884
|
-
self.span_id,
|
|
885
|
-
models.SpanAnnotation(
|
|
886
|
-
name=self.name,
|
|
887
|
-
annotator_kind=self.annotator_kind,
|
|
888
|
-
score=self.result.score if self.result else None,
|
|
889
|
-
label=self.result.label if self.result else None,
|
|
890
|
-
explanation=self.result.explanation if self.result else None,
|
|
891
|
-
metadata_=self.metadata or {},
|
|
892
|
-
identifier=self.identifier,
|
|
893
|
-
source="API",
|
|
894
|
-
user_id=user_id,
|
|
895
|
-
),
|
|
896
|
-
)
|
|
897
|
-
|
|
898
|
-
|
|
899
853
|
class AnnotateSpansRequestBody(RequestBody[list[SpanAnnotationData]]):
|
|
900
854
|
data: list[SpanAnnotationData]
|
|
901
855
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import gzip
|
|
2
2
|
import zlib
|
|
3
|
-
from
|
|
4
|
-
from typing import Any, Literal, Optional
|
|
3
|
+
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from fastapi import APIRouter, BackgroundTasks, Depends, Header, HTTPException, Path, Query
|
|
7
6
|
from google.protobuf.message import DecodeError
|
|
@@ -10,7 +9,7 @@ from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (
|
|
|
10
9
|
ExportTraceServiceResponse,
|
|
11
10
|
)
|
|
12
11
|
from pydantic import Field
|
|
13
|
-
from sqlalchemy import delete,
|
|
12
|
+
from sqlalchemy import delete, select
|
|
14
13
|
from starlette.concurrency import run_in_threadpool
|
|
15
14
|
from starlette.datastructures import State
|
|
16
15
|
from starlette.requests import Request
|
|
@@ -23,8 +22,9 @@ from starlette.status import (
|
|
|
23
22
|
from strawberry.relay import GlobalID
|
|
24
23
|
|
|
25
24
|
from phoenix.db import models
|
|
26
|
-
from phoenix.db.
|
|
27
|
-
from phoenix.db.insertion.
|
|
25
|
+
from phoenix.db.helpers import SupportedSQLDialect
|
|
26
|
+
from phoenix.db.insertion.helpers import as_kv, insert_on_conflict
|
|
27
|
+
from phoenix.server.api.routers.v1.annotations import TraceAnnotationData
|
|
28
28
|
from phoenix.server.api.types.node import from_global_id_with_expected_type
|
|
29
29
|
from phoenix.server.authorization import is_not_locked
|
|
30
30
|
from phoenix.server.bearer_auth import PhoenixUser
|
|
@@ -33,7 +33,11 @@ from phoenix.trace.otel import decode_otlp_span
|
|
|
33
33
|
from phoenix.utilities.project import get_project_name
|
|
34
34
|
|
|
35
35
|
from .models import V1RoutesBaseModel
|
|
36
|
-
from .utils import
|
|
36
|
+
from .utils import (
|
|
37
|
+
RequestBody,
|
|
38
|
+
ResponseBody,
|
|
39
|
+
add_errors_to_responses,
|
|
40
|
+
)
|
|
37
41
|
|
|
38
42
|
router = APIRouter(tags=["traces"])
|
|
39
43
|
|
|
@@ -105,54 +109,8 @@ async def post_traces(
|
|
|
105
109
|
)
|
|
106
110
|
|
|
107
111
|
|
|
108
|
-
class
|
|
109
|
-
|
|
110
|
-
score: Optional[float] = Field(default=None, description="The score assigned by the annotation")
|
|
111
|
-
explanation: Optional[str] = Field(
|
|
112
|
-
default=None, description="Explanation of the annotation result"
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
class TraceAnnotation(V1RoutesBaseModel):
|
|
117
|
-
trace_id: str = Field(description="OpenTelemetry Trace ID (hex format w/o 0x prefix)")
|
|
118
|
-
name: str = Field(description="The name of the annotation")
|
|
119
|
-
annotator_kind: Literal["LLM", "HUMAN"] = Field(
|
|
120
|
-
description="The kind of annotator used for the annotation"
|
|
121
|
-
)
|
|
122
|
-
result: Optional[TraceAnnotationResult] = Field(
|
|
123
|
-
default=None, description="The result of the annotation"
|
|
124
|
-
)
|
|
125
|
-
metadata: Optional[dict[str, Any]] = Field(
|
|
126
|
-
default=None, description="Metadata for the annotation"
|
|
127
|
-
)
|
|
128
|
-
identifier: str = Field(
|
|
129
|
-
default="",
|
|
130
|
-
description=(
|
|
131
|
-
"The identifier of the annotation. "
|
|
132
|
-
"If provided, the annotation will be updated if it already exists."
|
|
133
|
-
),
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
def as_precursor(self, *, user_id: Optional[int] = None) -> Precursors.TraceAnnotation:
|
|
137
|
-
return Precursors.TraceAnnotation(
|
|
138
|
-
datetime.now(timezone.utc),
|
|
139
|
-
self.trace_id,
|
|
140
|
-
models.TraceAnnotation(
|
|
141
|
-
name=self.name,
|
|
142
|
-
annotator_kind=self.annotator_kind,
|
|
143
|
-
score=self.result.score if self.result else None,
|
|
144
|
-
label=self.result.label if self.result else None,
|
|
145
|
-
explanation=self.result.explanation if self.result else None,
|
|
146
|
-
metadata_=self.metadata or {},
|
|
147
|
-
identifier=self.identifier,
|
|
148
|
-
source="APP",
|
|
149
|
-
user_id=user_id,
|
|
150
|
-
),
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
class AnnotateTracesRequestBody(RequestBody[list[TraceAnnotation]]):
|
|
155
|
-
data: list[TraceAnnotation] = Field(description="The trace annotations to be upserted")
|
|
112
|
+
class AnnotateTracesRequestBody(RequestBody[list[TraceAnnotationData]]):
|
|
113
|
+
data: list[TraceAnnotationData] = Field(description="The trace annotations to be upserted")
|
|
156
114
|
|
|
157
115
|
|
|
158
116
|
class InsertedTraceAnnotation(V1RoutesBaseModel):
|
|
@@ -208,10 +166,16 @@ async def annotate_traces(
|
|
|
208
166
|
status_code=HTTP_404_NOT_FOUND,
|
|
209
167
|
)
|
|
210
168
|
inserted_ids = []
|
|
169
|
+
dialect = SupportedSQLDialect(session.bind.dialect.name)
|
|
211
170
|
for p in precursors:
|
|
212
171
|
values = dict(as_kv(p.as_insertable(existing_traces[p.trace_id]).row))
|
|
213
172
|
trace_annotation_id = await session.scalar(
|
|
214
|
-
|
|
173
|
+
insert_on_conflict(
|
|
174
|
+
values,
|
|
175
|
+
dialect=dialect,
|
|
176
|
+
table=models.TraceAnnotation,
|
|
177
|
+
unique_by=("name", "trace_rowid", "identifier"),
|
|
178
|
+
).returning(models.TraceAnnotation.id)
|
|
215
179
|
)
|
|
216
180
|
inserted_ids.append(trace_annotation_id)
|
|
217
181
|
request.state.event_queue.put(TraceAnnotationInsertEvent(tuple(inserted_ids)))
|
|
@@ -15,9 +15,11 @@ from phoenix.server.api.context import Context
|
|
|
15
15
|
from phoenix.server.api.exceptions import BadRequest
|
|
16
16
|
from phoenix.server.api.input_types.DatasetVersionSort import DatasetVersionSort
|
|
17
17
|
from phoenix.server.api.types.DatasetExample import DatasetExample
|
|
18
|
+
from phoenix.server.api.types.DatasetExperimentAnnotationSummary import (
|
|
19
|
+
DatasetExperimentAnnotationSummary,
|
|
20
|
+
)
|
|
18
21
|
from phoenix.server.api.types.DatasetVersion import DatasetVersion
|
|
19
22
|
from phoenix.server.api.types.Experiment import Experiment, to_gql_experiment
|
|
20
|
-
from phoenix.server.api.types.ExperimentAnnotationSummary import ExperimentAnnotationSummary
|
|
21
23
|
from phoenix.server.api.types.node import from_global_id_with_expected_type
|
|
22
24
|
from phoenix.server.api.types.pagination import (
|
|
23
25
|
ConnectionArgs,
|
|
@@ -270,53 +272,13 @@ class Dataset(Node):
|
|
|
270
272
|
@strawberry.field
|
|
271
273
|
async def experiment_annotation_summaries(
|
|
272
274
|
self, info: Info[Context, None]
|
|
273
|
-
) -> list[
|
|
275
|
+
) -> list[DatasetExperimentAnnotationSummary]:
|
|
274
276
|
dataset_id = self.id_attr
|
|
275
|
-
|
|
276
|
-
select(
|
|
277
|
-
models.ExperimentRunAnnotation.name.label("annotation_name"),
|
|
278
|
-
func.avg(models.ExperimentRunAnnotation.score).label("mean_repetition_score"),
|
|
279
|
-
)
|
|
280
|
-
.select_from(models.ExperimentRunAnnotation)
|
|
281
|
-
.join(
|
|
282
|
-
models.ExperimentRun,
|
|
283
|
-
models.ExperimentRunAnnotation.experiment_run_id == models.ExperimentRun.id,
|
|
284
|
-
)
|
|
285
|
-
.join(
|
|
286
|
-
models.Experiment,
|
|
287
|
-
models.ExperimentRun.experiment_id == models.Experiment.id,
|
|
288
|
-
)
|
|
289
|
-
.where(models.Experiment.dataset_id == dataset_id)
|
|
290
|
-
.group_by(
|
|
291
|
-
models.ExperimentRun.dataset_example_id,
|
|
292
|
-
models.ExperimentRunAnnotation.name,
|
|
293
|
-
)
|
|
294
|
-
.subquery()
|
|
295
|
-
.alias("repetition_mean_scores_by_example")
|
|
296
|
-
)
|
|
297
|
-
repetition_mean_scores_subquery = (
|
|
298
|
-
select(
|
|
299
|
-
repetition_mean_scores_by_example_subquery.c.annotation_name.label(
|
|
300
|
-
"annotation_name"
|
|
301
|
-
),
|
|
302
|
-
func.avg(repetition_mean_scores_by_example_subquery.c.mean_repetition_score).label(
|
|
303
|
-
"mean_score"
|
|
304
|
-
),
|
|
305
|
-
)
|
|
306
|
-
.select_from(repetition_mean_scores_by_example_subquery)
|
|
307
|
-
.group_by(
|
|
308
|
-
repetition_mean_scores_by_example_subquery.c.annotation_name,
|
|
309
|
-
)
|
|
310
|
-
.subquery()
|
|
311
|
-
.alias("repetition_mean_scores")
|
|
312
|
-
)
|
|
313
|
-
repetitions_subquery = (
|
|
277
|
+
query = (
|
|
314
278
|
select(
|
|
315
279
|
models.ExperimentRunAnnotation.name.label("annotation_name"),
|
|
316
280
|
func.min(models.ExperimentRunAnnotation.score).label("min_score"),
|
|
317
281
|
func.max(models.ExperimentRunAnnotation.score).label("max_score"),
|
|
318
|
-
func.count().label("count"),
|
|
319
|
-
func.count(models.ExperimentRunAnnotation.error).label("error_count"),
|
|
320
282
|
)
|
|
321
283
|
.select_from(models.ExperimentRunAnnotation)
|
|
322
284
|
.join(
|
|
@@ -329,36 +291,16 @@ class Dataset(Node):
|
|
|
329
291
|
)
|
|
330
292
|
.where(models.Experiment.dataset_id == dataset_id)
|
|
331
293
|
.group_by(models.ExperimentRunAnnotation.name)
|
|
332
|
-
.
|
|
333
|
-
)
|
|
334
|
-
run_scores_query = (
|
|
335
|
-
select(
|
|
336
|
-
repetition_mean_scores_subquery.c.annotation_name.label("annotation_name"),
|
|
337
|
-
repetition_mean_scores_subquery.c.mean_score.label("mean_score"),
|
|
338
|
-
repetitions_subquery.c.min_score.label("min_score"),
|
|
339
|
-
repetitions_subquery.c.max_score.label("max_score"),
|
|
340
|
-
repetitions_subquery.c.count.label("count_"),
|
|
341
|
-
repetitions_subquery.c.error_count.label("error_count"),
|
|
342
|
-
)
|
|
343
|
-
.select_from(repetition_mean_scores_subquery)
|
|
344
|
-
.join(
|
|
345
|
-
repetitions_subquery,
|
|
346
|
-
repetitions_subquery.c.annotation_name
|
|
347
|
-
== repetition_mean_scores_subquery.c.annotation_name,
|
|
348
|
-
)
|
|
349
|
-
.order_by(repetition_mean_scores_subquery.c.annotation_name)
|
|
294
|
+
.order_by(models.ExperimentRunAnnotation.name)
|
|
350
295
|
)
|
|
351
296
|
async with info.context.db() as session:
|
|
352
297
|
return [
|
|
353
|
-
|
|
298
|
+
DatasetExperimentAnnotationSummary(
|
|
354
299
|
annotation_name=scores_tuple.annotation_name,
|
|
355
300
|
min_score=scores_tuple.min_score,
|
|
356
301
|
max_score=scores_tuple.max_score,
|
|
357
|
-
mean_score=scores_tuple.mean_score,
|
|
358
|
-
count=scores_tuple.count_,
|
|
359
|
-
error_count=scores_tuple.error_count,
|
|
360
302
|
)
|
|
361
|
-
async for scores_tuple in await session.stream(
|
|
303
|
+
async for scores_tuple in await session.stream(query)
|
|
362
304
|
]
|
|
363
305
|
|
|
364
306
|
@strawberry.field
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import TYPE_CHECKING, Annotated, Optional
|
|
3
|
+
|
|
4
|
+
import strawberry
|
|
5
|
+
from strawberry import Private
|
|
6
|
+
from strawberry.relay import Node, NodeID
|
|
7
|
+
from strawberry.scalars import JSON
|
|
8
|
+
from strawberry.types import Info
|
|
9
|
+
|
|
10
|
+
from phoenix.db import models
|
|
11
|
+
from phoenix.server.api.context import Context
|
|
12
|
+
from phoenix.server.api.interceptor import GqlValueMediator
|
|
13
|
+
|
|
14
|
+
from .Annotation import Annotation
|
|
15
|
+
from .AnnotationSource import AnnotationSource
|
|
16
|
+
from .AnnotatorKind import AnnotatorKind
|
|
17
|
+
from .User import User, to_gql_user
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from .Span import Span
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@strawberry.type
|
|
24
|
+
class DocumentAnnotation(Node, Annotation):
|
|
25
|
+
id_attr: NodeID[int]
|
|
26
|
+
user_id: Private[Optional[int]]
|
|
27
|
+
name: str = strawberry.field(
|
|
28
|
+
description="Name of the annotation, e.g. 'helpfulness' or 'relevance'."
|
|
29
|
+
)
|
|
30
|
+
annotator_kind: AnnotatorKind
|
|
31
|
+
label: Optional[str] = strawberry.field(
|
|
32
|
+
description="Value of the annotation in the form of a string, e.g. "
|
|
33
|
+
"'helpful' or 'not helpful'. Note that the label is not necessarily binary."
|
|
34
|
+
)
|
|
35
|
+
score: Optional[float] = strawberry.field(
|
|
36
|
+
description="Value of the annotation in the form of a numeric score.",
|
|
37
|
+
default=GqlValueMediator(),
|
|
38
|
+
)
|
|
39
|
+
explanation: Optional[str] = strawberry.field(
|
|
40
|
+
description="The annotator's explanation for the annotation result (i.e. "
|
|
41
|
+
"score or label, or both) given to the subject."
|
|
42
|
+
)
|
|
43
|
+
metadata: JSON
|
|
44
|
+
document_position: int
|
|
45
|
+
span_rowid: Private[int]
|
|
46
|
+
identifier: str
|
|
47
|
+
source: AnnotationSource
|
|
48
|
+
created_at: datetime = strawberry.field(
|
|
49
|
+
description="The date and time when the annotation was created."
|
|
50
|
+
)
|
|
51
|
+
updated_at: datetime = strawberry.field(
|
|
52
|
+
description="The date and time when the annotation was last updated."
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@strawberry.field
|
|
56
|
+
async def span(self) -> Annotated["Span", strawberry.lazy(".Span")]:
|
|
57
|
+
from phoenix.server.api.types.Span import Span
|
|
58
|
+
|
|
59
|
+
return Span(span_rowid=self.span_rowid)
|
|
60
|
+
|
|
61
|
+
@strawberry.field
|
|
62
|
+
async def user(
|
|
63
|
+
self,
|
|
64
|
+
info: Info[Context, None],
|
|
65
|
+
) -> Optional[User]:
|
|
66
|
+
if self.user_id is None:
|
|
67
|
+
return None
|
|
68
|
+
user = await info.context.data_loaders.users.load(self.user_id)
|
|
69
|
+
if user is None:
|
|
70
|
+
return None
|
|
71
|
+
return to_gql_user(user)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def to_gql_document_annotation(
|
|
75
|
+
annotation: models.DocumentAnnotation,
|
|
76
|
+
) -> DocumentAnnotation:
|
|
77
|
+
return DocumentAnnotation(
|
|
78
|
+
id_attr=annotation.id,
|
|
79
|
+
user_id=annotation.user_id,
|
|
80
|
+
name=annotation.name,
|
|
81
|
+
annotator_kind=AnnotatorKind(annotation.annotator_kind),
|
|
82
|
+
label=annotation.label,
|
|
83
|
+
score=annotation.score,
|
|
84
|
+
explanation=annotation.explanation,
|
|
85
|
+
metadata=annotation.metadata_,
|
|
86
|
+
span_rowid=annotation.span_rowid,
|
|
87
|
+
source=AnnotationSource(annotation.source),
|
|
88
|
+
identifier=annotation.identifier,
|
|
89
|
+
document_position=annotation.document_position,
|
|
90
|
+
created_at=annotation.created_at,
|
|
91
|
+
updated_at=annotation.updated_at,
|
|
92
|
+
)
|
phoenix/server/api/types/Span.py
CHANGED
|
@@ -34,8 +34,11 @@ from phoenix.server.api.input_types.SpanAnnotationSort import (
|
|
|
34
34
|
)
|
|
35
35
|
from phoenix.server.api.types.AnnotationSummary import AnnotationSummary
|
|
36
36
|
from phoenix.server.api.types.CostBreakdown import CostBreakdown
|
|
37
|
+
from phoenix.server.api.types.DocumentAnnotation import (
|
|
38
|
+
DocumentAnnotation,
|
|
39
|
+
to_gql_document_annotation,
|
|
40
|
+
)
|
|
37
41
|
from phoenix.server.api.types.DocumentRetrievalMetrics import DocumentRetrievalMetrics
|
|
38
|
-
from phoenix.server.api.types.Evaluation import DocumentAnnotation
|
|
39
42
|
from phoenix.server.api.types.ExampleRevisionInterface import ExampleRevision
|
|
40
43
|
from phoenix.server.api.types.GenerativeProvider import GenerativeProvider
|
|
41
44
|
from phoenix.server.api.types.MimeType import MimeType
|
|
@@ -639,7 +642,10 @@ class Span(Node):
|
|
|
639
642
|
self,
|
|
640
643
|
info: Info[Context, None],
|
|
641
644
|
) -> list[DocumentAnnotation]:
|
|
642
|
-
return
|
|
645
|
+
return [
|
|
646
|
+
to_gql_document_annotation(anno)
|
|
647
|
+
for anno in await info.context.data_loaders.document_evaluations.load(self.span_rowid)
|
|
648
|
+
]
|
|
643
649
|
|
|
644
650
|
@strawberry.field(
|
|
645
651
|
description="Retrieval metrics: NDCG@K, Precision@K, Reciprocal Rank, etc.",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from typing import Optional
|
|
1
|
+
from typing import TYPE_CHECKING, Annotated, Optional
|
|
2
2
|
|
|
3
3
|
import strawberry
|
|
4
4
|
from strawberry import Private
|
|
5
|
-
from strawberry.relay import
|
|
5
|
+
from strawberry.relay import Node, NodeID
|
|
6
6
|
from strawberry.scalars import JSON
|
|
7
7
|
from strawberry.types import Info
|
|
8
8
|
|
|
@@ -13,6 +13,9 @@ from phoenix.server.api.types.AnnotatorKind import AnnotatorKind
|
|
|
13
13
|
from .AnnotationSource import AnnotationSource
|
|
14
14
|
from .User import User, to_gql_user
|
|
15
15
|
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from .Trace import Trace
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
@strawberry.type
|
|
18
21
|
class TraceAnnotation(Node):
|
|
@@ -24,15 +27,15 @@ class TraceAnnotation(Node):
|
|
|
24
27
|
score: Optional[float]
|
|
25
28
|
explanation: Optional[str]
|
|
26
29
|
metadata: JSON
|
|
27
|
-
trace_rowid: Private[
|
|
30
|
+
trace_rowid: Private[int]
|
|
28
31
|
identifier: str
|
|
29
32
|
source: AnnotationSource
|
|
30
33
|
|
|
31
34
|
@strawberry.field
|
|
32
|
-
async def
|
|
35
|
+
async def trace(self) -> Annotated["Trace", strawberry.lazy(".Trace")]:
|
|
33
36
|
from phoenix.server.api.types.Trace import Trace
|
|
34
37
|
|
|
35
|
-
return
|
|
38
|
+
return Trace(trace_rowid=self.trace_rowid)
|
|
36
39
|
|
|
37
40
|
@strawberry.field
|
|
38
41
|
async def user(
|
|
@@ -687,6 +687,33 @@
|
|
|
687
687
|
}
|
|
688
688
|
]
|
|
689
689
|
},
|
|
690
|
+
{
|
|
691
|
+
"name": "gemini-2.5-flash-image-preview",
|
|
692
|
+
"name_pattern": "gemini-2\\.5-flash-image-preview",
|
|
693
|
+
"source": "litellm",
|
|
694
|
+
"token_prices": [
|
|
695
|
+
{
|
|
696
|
+
"base_rate": 3e-7,
|
|
697
|
+
"is_prompt": true,
|
|
698
|
+
"token_type": "input"
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
"base_rate": 2.5e-6,
|
|
702
|
+
"is_prompt": false,
|
|
703
|
+
"token_type": "output"
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"base_rate": 7.5e-8,
|
|
707
|
+
"is_prompt": true,
|
|
708
|
+
"token_type": "cache_read"
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
"base_rate": 1e-6,
|
|
712
|
+
"is_prompt": true,
|
|
713
|
+
"token_type": "audio"
|
|
714
|
+
}
|
|
715
|
+
]
|
|
716
|
+
},
|
|
690
717
|
{
|
|
691
718
|
"name": "gemini-2.5-flash-lite",
|
|
692
719
|
"name_pattern": "gemini-2\\.5-flash-lite",
|
|
@@ -2308,6 +2335,70 @@
|
|
|
2308
2335
|
}
|
|
2309
2336
|
]
|
|
2310
2337
|
},
|
|
2338
|
+
{
|
|
2339
|
+
"name": "gpt-realtime",
|
|
2340
|
+
"name_pattern": "gpt-realtime",
|
|
2341
|
+
"source": "litellm",
|
|
2342
|
+
"token_prices": [
|
|
2343
|
+
{
|
|
2344
|
+
"base_rate": 4e-6,
|
|
2345
|
+
"is_prompt": true,
|
|
2346
|
+
"token_type": "input"
|
|
2347
|
+
},
|
|
2348
|
+
{
|
|
2349
|
+
"base_rate": 0.000016,
|
|
2350
|
+
"is_prompt": false,
|
|
2351
|
+
"token_type": "output"
|
|
2352
|
+
},
|
|
2353
|
+
{
|
|
2354
|
+
"base_rate": 4e-7,
|
|
2355
|
+
"is_prompt": true,
|
|
2356
|
+
"token_type": "cache_read"
|
|
2357
|
+
},
|
|
2358
|
+
{
|
|
2359
|
+
"base_rate": 0.000032,
|
|
2360
|
+
"is_prompt": true,
|
|
2361
|
+
"token_type": "audio"
|
|
2362
|
+
},
|
|
2363
|
+
{
|
|
2364
|
+
"base_rate": 0.000064,
|
|
2365
|
+
"is_prompt": false,
|
|
2366
|
+
"token_type": "audio"
|
|
2367
|
+
}
|
|
2368
|
+
]
|
|
2369
|
+
},
|
|
2370
|
+
{
|
|
2371
|
+
"name": "gpt-realtime-2025-08-28",
|
|
2372
|
+
"name_pattern": "gpt-realtime-2025-08-28",
|
|
2373
|
+
"source": "litellm",
|
|
2374
|
+
"token_prices": [
|
|
2375
|
+
{
|
|
2376
|
+
"base_rate": 4e-6,
|
|
2377
|
+
"is_prompt": true,
|
|
2378
|
+
"token_type": "input"
|
|
2379
|
+
},
|
|
2380
|
+
{
|
|
2381
|
+
"base_rate": 0.000016,
|
|
2382
|
+
"is_prompt": false,
|
|
2383
|
+
"token_type": "output"
|
|
2384
|
+
},
|
|
2385
|
+
{
|
|
2386
|
+
"base_rate": 4e-7,
|
|
2387
|
+
"is_prompt": true,
|
|
2388
|
+
"token_type": "cache_read"
|
|
2389
|
+
},
|
|
2390
|
+
{
|
|
2391
|
+
"base_rate": 0.000032,
|
|
2392
|
+
"is_prompt": true,
|
|
2393
|
+
"token_type": "audio"
|
|
2394
|
+
},
|
|
2395
|
+
{
|
|
2396
|
+
"base_rate": 0.000064,
|
|
2397
|
+
"is_prompt": false,
|
|
2398
|
+
"token_type": "audio"
|
|
2399
|
+
}
|
|
2400
|
+
]
|
|
2401
|
+
},
|
|
2311
2402
|
{
|
|
2312
2403
|
"name": "o1",
|
|
2313
2404
|
"name_pattern": "o1",
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_components-
|
|
3
|
-
"file": "assets/components-
|
|
2
|
+
"_components-BjW5gAwL.js": {
|
|
3
|
+
"file": "assets/components-BjW5gAwL.js",
|
|
4
4
|
"name": "components",
|
|
5
5
|
"imports": [
|
|
6
6
|
"_vendor-RdRDaQiR.js",
|
|
7
|
-
"_pages-
|
|
7
|
+
"_pages-CQfUODtD.js",
|
|
8
8
|
"_vendor-arizeai-DsYDNOqt.js",
|
|
9
9
|
"_vendor-codemirror-BzJDUbEx.js",
|
|
10
10
|
"_vendor-three-BLWp5bic.js"
|
|
11
11
|
]
|
|
12
12
|
},
|
|
13
|
-
"_pages-
|
|
14
|
-
"file": "assets/pages-
|
|
13
|
+
"_pages-CQfUODtD.js": {
|
|
14
|
+
"file": "assets/pages-CQfUODtD.js",
|
|
15
15
|
"name": "pages",
|
|
16
16
|
"imports": [
|
|
17
17
|
"_vendor-RdRDaQiR.js",
|
|
18
18
|
"_vendor-arizeai-DsYDNOqt.js",
|
|
19
|
-
"_components-
|
|
19
|
+
"_components-BjW5gAwL.js",
|
|
20
20
|
"_vendor-codemirror-BzJDUbEx.js",
|
|
21
21
|
"_vendor-recharts-BTHn5Y2R.js"
|
|
22
22
|
]
|
|
@@ -75,15 +75,15 @@
|
|
|
75
75
|
"name": "vendor-three"
|
|
76
76
|
},
|
|
77
77
|
"index.tsx": {
|
|
78
|
-
"file": "assets/index-
|
|
78
|
+
"file": "assets/index-3OI8VV_W.js",
|
|
79
79
|
"name": "index",
|
|
80
80
|
"src": "index.tsx",
|
|
81
81
|
"isEntry": true,
|
|
82
82
|
"imports": [
|
|
83
83
|
"_vendor-RdRDaQiR.js",
|
|
84
84
|
"_vendor-arizeai-DsYDNOqt.js",
|
|
85
|
-
"_pages-
|
|
86
|
-
"_components-
|
|
85
|
+
"_pages-CQfUODtD.js",
|
|
86
|
+
"_components-BjW5gAwL.js",
|
|
87
87
|
"_vendor-three-BLWp5bic.js",
|
|
88
88
|
"_vendor-codemirror-BzJDUbEx.js",
|
|
89
89
|
"_vendor-shiki-BAcocHFl.js",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as p,j as e,u as st,a as rn,e as qn,s as xa,b as Ta,c as zn,d as Za,f as So,g as Xe,h as xo,i as To,k as Ua,l as s,m as bn,p as ca,n as Nn,R as Ge,o as E,q as ct,t as Fn,v as Ao,C as na,w as Io,x as Mo,L as _l,y as Dl,z as Kl,A as Oe,B as tn,D as W,E as zo,F as cn,G as Fo,H as Eo,I as $e,J as an,K as j,M as _o,N as oe,O as yn,P as Dn,Q as Pl,S as xn,T as da,U as m,V as Vl,$ as N,W as Do,X as V,Y as Ol,Z as Rl,_ as Ae,a0 as Ko,a1 as Po,a2 as vn,a3 as Vo,a4 as B,a5 as gn,a6 as P,a7 as G,a8 as ee,a9 as Nl,aa as $l,ab as Oo,ac as Bl,ad as Ro,ae as Hl,af as No,ag as $o,ah as jl,ai as Bo,aj as Ho,ak as jo,al as Zl,am as Zo,an as Uo,ao as Go,ap as Te,aq as Ul,ar as Be,as as Qo,at as Wo,au as Qe,av as Ga,aw as Qa,ax as Wa,ay as U,az as Cn,aA as Ut,aB as Gl,aC as Ql,aD as qo,aE as Xo,aF as Yo,aG as Jo,aH as e1,aI as n1,aJ as Wl,aK as a1,aL as t1,aM as l1,aN as i1,aO as r1,aP as o1,aQ as s1,aR as dt,aS as te,aT as c1,aU as d1,aV as ql,aW as u1,aX as g1,aY as Xl,aZ as Ke,a_ as Yl,a$ as Gt,b0 as m1,b1 as Jl,b2 as pe,b3 as p1,b4 as ut,b5 as h1,b6 as f1,b7 as b1,b8 as y1,b9 as Qt,ba as ei,bb as v1,bc as C1,bd as k1,be as gt,bf as L1,bg as w1,bh as ua,bi as S1,bj as x1,bk as T1,bl as ni,bm as A1,bn as I1,bo as M1,bp as z1,bq as F1,br as E1,bs as _1,bt as Wt,bu as D1,bv as Aa,bw as K1,bx as P1,by as V1,bz as O1,bA as R1,bB as N1,bC as $1,bD as B1,bE as H1,bF as Xn}from"./vendor-RdRDaQiR.js";import{a as qt,R as j1,b as Z1,c as U1,m as G1,T as Q1,A as W1,S as q1,d as X1,e as Y1,f as J1,u as es}from"./pages-
|
|
1
|
+
import{r as p,j as e,u as st,a as rn,e as qn,s as xa,b as Ta,c as zn,d as Za,f as So,g as Xe,h as xo,i as To,k as Ua,l as s,m as bn,p as ca,n as Nn,R as Ge,o as E,q as ct,t as Fn,v as Ao,C as na,w as Io,x as Mo,L as _l,y as Dl,z as Kl,A as Oe,B as tn,D as W,E as zo,F as cn,G as Fo,H as Eo,I as $e,J as an,K as j,M as _o,N as oe,O as yn,P as Dn,Q as Pl,S as xn,T as da,U as m,V as Vl,$ as N,W as Do,X as V,Y as Ol,Z as Rl,_ as Ae,a0 as Ko,a1 as Po,a2 as vn,a3 as Vo,a4 as B,a5 as gn,a6 as P,a7 as G,a8 as ee,a9 as Nl,aa as $l,ab as Oo,ac as Bl,ad as Ro,ae as Hl,af as No,ag as $o,ah as jl,ai as Bo,aj as Ho,ak as jo,al as Zl,am as Zo,an as Uo,ao as Go,ap as Te,aq as Ul,ar as Be,as as Qo,at as Wo,au as Qe,av as Ga,aw as Qa,ax as Wa,ay as U,az as Cn,aA as Ut,aB as Gl,aC as Ql,aD as qo,aE as Xo,aF as Yo,aG as Jo,aH as e1,aI as n1,aJ as Wl,aK as a1,aL as t1,aM as l1,aN as i1,aO as r1,aP as o1,aQ as s1,aR as dt,aS as te,aT as c1,aU as d1,aV as ql,aW as u1,aX as g1,aY as Xl,aZ as Ke,a_ as Yl,a$ as Gt,b0 as m1,b1 as Jl,b2 as pe,b3 as p1,b4 as ut,b5 as h1,b6 as f1,b7 as b1,b8 as y1,b9 as Qt,ba as ei,bb as v1,bc as C1,bd as k1,be as gt,bf as L1,bg as w1,bh as ua,bi as S1,bj as x1,bk as T1,bl as ni,bm as A1,bn as I1,bo as M1,bp as z1,bq as F1,br as E1,bs as _1,bt as Wt,bu as D1,bv as Aa,bw as K1,bx as P1,by as V1,bz as O1,bA as R1,bB as N1,bC as $1,bD as B1,bE as H1,bF as Xn}from"./vendor-RdRDaQiR.js";import{a as qt,R as j1,b as Z1,c as U1,m as G1,T as Q1,A as W1,S as q1,d as X1,e as Y1,f as J1,u as es}from"./pages-CQfUODtD.js";import{u as ns,_ as as,a as ts,F as ai,I as ls,b as is,c as rs,d as os,e as ss,f as cs,g as ds,P as us,h as gs,i as ms,j as ps,T as hs,k as fs}from"./vendor-arizeai-DsYDNOqt.js";import{L as ti,a as li,j as ii,E as mt,k as ri,d as oi,l as qa,b as si,h as bs,c as ys,e as vs,f as Cs,g as ks,i as Ls,s as ws,m as $n,n as Bn,R as Hn,p as Ss,o as xs}from"./vendor-codemirror-BzJDUbEx.js";import{V as Ts}from"./vendor-three-BLWp5bic.js";const ci=function(){var n={defaultValue:null,kind:"LocalArgument",name:"clusters"},a={defaultValue:null,kind:"LocalArgument",name:"dataQualityMetricColumnName"},t={defaultValue:null,kind:"LocalArgument",name:"fetchDataQualityMetric"},l={defaultValue:null,kind:"LocalArgument",name:"fetchPerformanceMetric"},i={defaultValue:null,kind:"LocalArgument",name:"performanceMetric"},r=[{alias:null,args:null,kind:"ScalarField",name:"primaryValue",storageKey:null},{alias:null,args:null,kind:"ScalarField",name:"referenceValue",storageKey:null}],o=[{alias:null,args:[{kind:"Variable",name:"clusters",variableName:"clusters"}],concreteType:"Cluster",kind:"LinkedField",name:"clusters",plural:!0,selections:[{alias:null,args:null,kind:"ScalarField",name:"id",storageKey:null},{alias:null,args:null,kind:"ScalarField",name:"eventIds",storageKey:null},{alias:null,args:null,kind:"ScalarField",name:"driftRatio",storageKey:null},{alias:null,args:null,kind:"ScalarField",name:"primaryToCorpusRatio",storageKey:null},{condition:"fetchDataQualityMetric",kind:"Condition",passingValue:!0,selections:[{alias:null,args:[{fields:[{kind:"Variable",name:"columnName",variableName:"dataQualityMetricColumnName"},{kind:"Literal",name:"metric",value:"mean"}],kind:"ObjectValue",name:"metric"}],concreteType:"DatasetValues",kind:"LinkedField",name:"dataQualityMetric",plural:!1,selections:r,storageKey:null}]},{condition:"fetchPerformanceMetric",kind:"Condition",passingValue:!0,selections:[{alias:null,args:[{fields:[{kind:"Variable",name:"metric",variableName:"performanceMetric"}],kind:"ObjectValue",name:"metric"}],concreteType:"DatasetValues",kind:"LinkedField",name:"performanceMetric",plural:!1,selections:r,storageKey:null}]}],storageKey:null}];return{fragment:{argumentDefinitions:[n,a,t,l,i],kind:"Fragment",metadata:null,name:"pointCloudStore_clusterMetricsQuery",selections:o,type:"Query",abstractKey:null},kind:"Request",operation:{argumentDefinitions:[n,t,a,l,i],kind:"Operation",name:"pointCloudStore_clusterMetricsQuery",selections:o},params:{cacheID:"86666967012812887ac0a0149d2d2535",id:null,metadata:{},name:"pointCloudStore_clusterMetricsQuery",operationKind:"query",text:`query pointCloudStore_clusterMetricsQuery(
|
|
2
2
|
$clusters: [ClusterInput!]!
|
|
3
3
|
$fetchDataQualityMetric: Boolean!
|
|
4
4
|
$dataQualityMetricColumnName: String
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{U as g,j as o,c_ as f,eD as h,eE as v,eF as y,l as r,cl as x,eG as a,r as z,o as w,eH as P}from"./vendor-RdRDaQiR.js";import{r as k,s as S}from"./vendor-arizeai-DsYDNOqt.js";import{L,g as C,r as R,h as j,i as E,F as I,j as D,P as A,k as F,M as t,l as T,D as G,n as M,E as _,o as O,p as N,q as V,s as q,t as d,v as U,w as W,x as B,y as $,z as H,B as K,C as Y,G as J,H as Q,I as X,J as Z,K as oo,N as ao,O as lo,Q as ro,U as co,V as go,W as m,X as p,Y as eo,Z as bo,_ as no,$ as io,a0 as so,a1 as to,a2 as mo,a3 as po,a4 as uo,a5 as fo,a6 as ho,a7 as vo,a8 as yo,a9 as xo,aa as zo,ab as wo,ac as Po,ad as ko,ae as So,af as Lo,ag as Co,ah as Ro,ai as jo,aj as Eo,ak as Io,al as Do,am as Ao,an as Fo,ao as To,ap as Go,aq as Mo,ar as _o,as as Oo,at as No,au as Vo,av as qo,aw as Uo,ax as Wo,ay as n,az as Bo,aA as $o,aB as Ho,aC as Ko,aD as Yo,aE as Jo}from"./pages-
|
|
1
|
+
import{U as g,j as o,c_ as f,eD as h,eE as v,eF as y,l as r,cl as x,eG as a,r as z,o as w,eH as P}from"./vendor-RdRDaQiR.js";import{r as k,s as S}from"./vendor-arizeai-DsYDNOqt.js";import{L,g as C,r as R,h as j,i as E,F as I,j as D,P as A,k as F,M as t,l as T,D as G,n as M,E as _,o as O,p as N,q as V,s as q,t as d,v as U,w as W,x as B,y as $,z as H,B as K,C as Y,G as J,H as Q,I as X,J as Z,K as oo,N as ao,O as lo,Q as ro,U as co,V as go,W as m,X as p,Y as eo,Z as bo,_ as no,$ as io,a0 as so,a1 as to,a2 as mo,a3 as po,a4 as uo,a5 as fo,a6 as ho,a7 as vo,a8 as yo,a9 as xo,aa as zo,ab as wo,ac as Po,ad as ko,ae as So,af as Lo,ag as Co,ah as Ro,ai as jo,aj as Eo,ak as Io,al as Do,am as Ao,an as Fo,ao as To,ap as Go,aq as Mo,ar as _o,as as Oo,at as No,au as Vo,av as qo,aw as Uo,ax as Wo,ay as n,az as Bo,aA as $o,aB as Ho,aC as Ko,aD as Yo,aE as Jo}from"./pages-CQfUODtD.js";import{fR as Qo,cY as Xo,U as Zo,fS as oa,fT as aa,fU as la}from"./components-BjW5gAwL.js";import"./vendor-three-BLWp5bic.js";import"./vendor-codemirror-BzJDUbEx.js";import"./vendor-shiki-BAcocHFl.js";import"./vendor-recharts-BTHn5Y2R.js";(function(){const b=document.createElement("link").relList;if(b&&b.supports&&b.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))s(c);new MutationObserver(c=>{for(const e of c)if(e.type==="childList")for(const i of e.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function u(c){const e={};return c.integrity&&(e.integrity=c.integrity),c.referrerPolicy&&(e.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?e.credentials="include":c.crossOrigin==="anonymous"?e.credentials="omit":e.credentials="same-origin",e}function s(c){if(c.ep)return;c.ep=!0;const e=u(c);fetch(c.href,e)}})();const ra=g`
|
|
2
2
|
:root,
|
|
3
3
|
.ac-theme {
|
|
4
4
|
--ac-global-dimension-scale-factor: 1;
|