arize-phoenix 4.25.0__py3-none-any.whl → 4.27.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.

phoenix/server/app.py CHANGED
@@ -2,19 +2,23 @@ import asyncio
2
2
  import contextlib
3
3
  import json
4
4
  import logging
5
+ from datetime import datetime, timedelta, timezone
5
6
  from functools import cached_property
6
7
  from pathlib import Path
8
+ from types import MethodType
7
9
  from typing import (
8
10
  TYPE_CHECKING,
9
11
  Any,
10
12
  AsyncContextManager,
11
13
  AsyncIterator,
14
+ Awaitable,
12
15
  Callable,
13
16
  Dict,
14
17
  Iterable,
15
18
  List,
16
19
  NamedTuple,
17
20
  Optional,
21
+ Set,
18
22
  Tuple,
19
23
  Union,
20
24
  cast,
@@ -25,11 +29,9 @@ from fastapi import APIRouter, FastAPI
25
29
  from fastapi.middleware.gzip import GZipMiddleware
26
30
  from fastapi.responses import FileResponse
27
31
  from fastapi.utils import is_body_allowed_for_status_code
28
- from sqlalchemy.ext.asyncio import (
29
- AsyncEngine,
30
- AsyncSession,
31
- async_sessionmaker,
32
- )
32
+ from sqlalchemy import select
33
+ from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
34
+ from starlette.datastructures import State as StarletteState
33
35
  from starlette.exceptions import HTTPException
34
36
  from starlette.middleware import Middleware
35
37
  from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
@@ -44,12 +46,9 @@ from typing_extensions import TypeAlias
44
46
 
45
47
  import phoenix
46
48
  import phoenix.trace.v1 as pb
47
- from phoenix.config import (
48
- DEFAULT_PROJECT_NAME,
49
- SERVER_DIR,
50
- server_instrumentation_is_enabled,
51
- )
49
+ from phoenix.config import DEFAULT_PROJECT_NAME, SERVER_DIR, server_instrumentation_is_enabled
52
50
  from phoenix.core.model_schema import Model
51
+ from phoenix.db import models
53
52
  from phoenix.db.bulk_inserter import BulkInserter
54
53
  from phoenix.db.engines import create_engine
55
54
  from phoenix.db.helpers import SupportedSQLDialect
@@ -80,6 +79,7 @@ from phoenix.server.api.dataloaders import (
80
79
  TokenCountDataLoader,
81
80
  TraceRowIdsDataLoader,
82
81
  )
82
+ from phoenix.server.api.routers.auth import router as auth_router
83
83
  from phoenix.server.api.routers.v1 import REST_API_VERSION
84
84
  from phoenix.server.api.routers.v1 import router as v1_router
85
85
  from phoenix.server.api.schema import schema
@@ -90,9 +90,17 @@ from phoenix.server.telemetry import initialize_opentelemetry_tracer_provider
90
90
  from phoenix.server.types import (
91
91
  CanGetLastUpdatedAt,
92
92
  CanPutItem,
93
+ DaemonTask,
93
94
  DbSessionFactory,
94
95
  LastUpdatedAt,
95
96
  )
97
+ from phoenix.trace.fixtures import (
98
+ get_evals_from_fixture,
99
+ get_trace_fixture_by_name,
100
+ load_example_traces,
101
+ reset_fixture_span_ids_and_timestamps,
102
+ )
103
+ from phoenix.trace.otel import decode_otlp_span, encode_span_to_otlp
96
104
  from phoenix.trace.schemas import Span
97
105
  from phoenix.utilities.client import PHOENIX_SERVER_VERSION_HEADER
98
106
 
@@ -100,12 +108,23 @@ if TYPE_CHECKING:
100
108
  from opentelemetry.trace import TracerProvider
101
109
 
102
110
  logger = logging.getLogger(__name__)
111
+ logger.setLevel(logging.INFO)
103
112
  logger.addHandler(logging.NullHandler())
104
113
 
105
114
  router = APIRouter(include_in_schema=False)
106
115
 
107
116
  templates = Jinja2Templates(directory=SERVER_DIR / "templates")
108
117
 
118
+ """
119
+ Threshold (in minutes) to determine if database is booted up for the first time.
120
+
121
+ Used to assess whether the `default` project was created recently.
122
+ If so, demo data is automatically ingested upon initial boot up to populate the database.
123
+ """
124
+ NEW_DB_AGE_THRESHOLD_MINUTES = 2
125
+
126
+ ProjectName: TypeAlias = str
127
+
109
128
 
110
129
  class AppConfig(NamedTuple):
111
130
  has_inferences: bool
@@ -223,9 +242,99 @@ def _db(engine: AsyncEngine) -> Callable[[], AsyncContextManager[AsyncSession]]:
223
242
  return factory
224
243
 
225
244
 
245
+ class Scaffolder(DaemonTask):
246
+ def __init__(
247
+ self,
248
+ db: DbSessionFactory,
249
+ queue_span: Callable[[Span, ProjectName], Awaitable[None]],
250
+ queue_evaluation: Callable[[pb.Evaluation], Awaitable[None]],
251
+ tracing_fixture_names: Set[str] = set(),
252
+ force_fixture_ingestion: bool = False,
253
+ ) -> None:
254
+ super().__init__()
255
+ self._db = db
256
+ self._queue_span = queue_span
257
+ self._queue_evaluation = queue_evaluation
258
+ self._tracing_fixtures = set(
259
+ get_trace_fixture_by_name(name) for name in tracing_fixture_names
260
+ )
261
+ self._force_fixture_ingestion = force_fixture_ingestion
262
+
263
+ async def __aenter__(self) -> None:
264
+ await self.start()
265
+
266
+ async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
267
+ await self.stop()
268
+
269
+ async def _run(self) -> None:
270
+ """
271
+ Main entry point for Scaffolder.
272
+ Determines whether to load fixtures and handles them.
273
+ """
274
+ if await self._should_load_fixtures():
275
+ logger.info("Loading trace fixtures.")
276
+ await self._handle_tracing_fixtures()
277
+ logger.info("Finished loading fixtures.")
278
+ else:
279
+ logger.info("DB is not new, avoid loading demo fixtures.")
280
+
281
+ async def _should_load_fixtures(self) -> bool:
282
+ if self._force_fixture_ingestion:
283
+ return True
284
+
285
+ async with self._db() as session:
286
+ created_at = await session.scalar(
287
+ select(models.Project.created_at).where(models.Project.name == "default")
288
+ )
289
+ if created_at is None:
290
+ return False
291
+
292
+ is_new_db = datetime.now(timezone.utc) - created_at < timedelta(
293
+ minutes=NEW_DB_AGE_THRESHOLD_MINUTES
294
+ )
295
+ return is_new_db
296
+
297
+ async def _handle_tracing_fixtures(self) -> None:
298
+ """
299
+ Main handler for processing trace fixtures. Process each fixture by
300
+ loading its trace dataframe, gettting and processings its
301
+ spans and evals, and queuing.
302
+ """
303
+ loop = asyncio.get_running_loop()
304
+ for fixture in self._tracing_fixtures:
305
+ try:
306
+ trace_ds = await loop.run_in_executor(None, load_example_traces, fixture.name)
307
+
308
+ fixture_spans, fixture_evals = await loop.run_in_executor(
309
+ None,
310
+ reset_fixture_span_ids_and_timestamps,
311
+ (
312
+ # Apply `encode` here because legacy jsonl files contains UUIDs as strings.
313
+ # `encode` removes the hyphens in the UUIDs.
314
+ decode_otlp_span(encode_span_to_otlp(span))
315
+ for span in trace_ds.to_spans()
316
+ ),
317
+ get_evals_from_fixture(fixture.name),
318
+ )
319
+
320
+ project_name = fixture.project_name or fixture.name
321
+ logger.info(f"Loading '{project_name}' fixtures...")
322
+ for span in fixture_spans:
323
+ await self._queue_span(span, project_name)
324
+ for evaluation in fixture_evals:
325
+ await self._queue_evaluation(evaluation)
326
+
327
+ except FileNotFoundError:
328
+ logger.warning(f"Fixture file not found for '{fixture.name}'")
329
+ except ValueError as e:
330
+ logger.error(f"Error processing fixture '{fixture.name}': {e}")
331
+ except Exception as e:
332
+ logger.error(f"Unexpected error processing fixture '{fixture.name}': {e}")
333
+
334
+
226
335
  def _lifespan(
227
336
  *,
228
- dialect: SupportedSQLDialect,
337
+ db: DbSessionFactory,
229
338
  bulk_inserter: BulkInserter,
230
339
  dml_event_handler: DmlEventHandler,
231
340
  tracer_provider: Optional["TracerProvider"] = None,
@@ -233,11 +342,13 @@ def _lifespan(
233
342
  startup_callbacks: Iterable[Callable[[], None]] = (),
234
343
  shutdown_callbacks: Iterable[Callable[[], None]] = (),
235
344
  read_only: bool = False,
345
+ tracing_fixture_names: Set[str] = set(),
346
+ force_fixture_ingestion: bool = False,
236
347
  ) -> StatefulLifespan[FastAPI]:
237
348
  @contextlib.asynccontextmanager
238
349
  async def lifespan(_: FastAPI) -> AsyncIterator[Dict[str, Any]]:
239
350
  global DB_MUTEX
240
- DB_MUTEX = asyncio.Lock() if dialect is SupportedSQLDialect.SQLITE else None
351
+ DB_MUTEX = asyncio.Lock() if db.dialect is SupportedSQLDialect.SQLITE else None
241
352
  async with bulk_inserter as (
242
353
  enqueue,
243
354
  queue_span,
@@ -248,7 +359,13 @@ def _lifespan(
248
359
  disabled=read_only,
249
360
  tracer_provider=tracer_provider,
250
361
  enable_prometheus=enable_prometheus,
251
- ), dml_event_handler:
362
+ ), dml_event_handler, Scaffolder(
363
+ db=db,
364
+ queue_span=queue_span,
365
+ queue_evaluation=queue_evaluation,
366
+ tracing_fixture_names=tracing_fixture_names,
367
+ force_fixture_ingestion=force_fixture_ingestion,
368
+ ):
252
369
  for callback in startup_callbacks:
253
370
  callback()
254
371
  yield {
@@ -314,17 +431,19 @@ def create_graphql_router(
314
431
  dataset_example_spans=DatasetExampleSpansDataLoader(db),
315
432
  document_evaluation_summaries=DocumentEvaluationSummaryDataLoader(
316
433
  db,
317
- cache_map=cache_for_dataloaders.document_evaluation_summary
318
- if cache_for_dataloaders
319
- else None,
434
+ cache_map=(
435
+ cache_for_dataloaders.document_evaluation_summary
436
+ if cache_for_dataloaders
437
+ else None
438
+ ),
320
439
  ),
321
440
  document_evaluations=DocumentEvaluationsDataLoader(db),
322
441
  document_retrieval_metrics=DocumentRetrievalMetricsDataLoader(db),
323
442
  annotation_summaries=AnnotationSummaryDataLoader(
324
443
  db,
325
- cache_map=cache_for_dataloaders.annotation_summary
326
- if cache_for_dataloaders
327
- else None,
444
+ cache_map=(
445
+ cache_for_dataloaders.annotation_summary if cache_for_dataloaders else None
446
+ ),
328
447
  ),
329
448
  experiment_annotation_summaries=ExperimentAnnotationSummaryDataLoader(db),
330
449
  experiment_error_rates=ExperimentErrorRatesDataLoader(db),
@@ -332,15 +451,17 @@ def create_graphql_router(
332
451
  experiment_sequence_number=ExperimentSequenceNumberDataLoader(db),
333
452
  latency_ms_quantile=LatencyMsQuantileDataLoader(
334
453
  db,
335
- cache_map=cache_for_dataloaders.latency_ms_quantile
336
- if cache_for_dataloaders
337
- else None,
454
+ cache_map=(
455
+ cache_for_dataloaders.latency_ms_quantile if cache_for_dataloaders else None
456
+ ),
338
457
  ),
339
458
  min_start_or_max_end_times=MinStartOrMaxEndTimeDataLoader(
340
459
  db,
341
- cache_map=cache_for_dataloaders.min_start_or_max_end_time
342
- if cache_for_dataloaders
343
- else None,
460
+ cache_map=(
461
+ cache_for_dataloaders.min_start_or_max_end_time
462
+ if cache_for_dataloaders
463
+ else None
464
+ ),
344
465
  ),
345
466
  record_counts=RecordCountDataLoader(
346
467
  db,
@@ -435,6 +556,8 @@ def create_app(
435
556
  startup_callbacks: Iterable[Callable[[], None]] = (),
436
557
  shutdown_callbacks: Iterable[Callable[[], None]] = (),
437
558
  secret: Optional[str] = None,
559
+ tracing_fixture_names: Set[str] = set(),
560
+ force_fixture_ingestion: bool = False,
438
561
  ) -> FastAPI:
439
562
  startup_callbacks_list: List[Callable[[], None]] = list(startup_callbacks)
440
563
  shutdown_callbacks_list: List[Callable[[], None]] = list(shutdown_callbacks)
@@ -507,11 +630,12 @@ def create_app(
507
630
  prometheus_middlewares = [Middleware(PrometheusMiddleware)]
508
631
  else:
509
632
  prometheus_middlewares = []
633
+
510
634
  app = FastAPI(
511
635
  title="Arize-Phoenix REST API",
512
636
  version=REST_API_VERSION,
513
637
  lifespan=_lifespan(
514
- dialect=db.dialect,
638
+ db=db,
515
639
  read_only=read_only,
516
640
  bulk_inserter=bulk_inserter,
517
641
  dml_event_handler=dml_event_handler,
@@ -519,6 +643,8 @@ def create_app(
519
643
  enable_prometheus=enable_prometheus,
520
644
  shutdown_callbacks=shutdown_callbacks_list,
521
645
  startup_callbacks=startup_callbacks_list,
646
+ tracing_fixture_names=tracing_fixture_names,
647
+ force_fixture_ingestion=force_fixture_ingestion,
522
648
  ),
523
649
  middleware=[
524
650
  Middleware(HeadersMiddleware),
@@ -536,6 +662,8 @@ def create_app(
536
662
  app.include_router(router)
537
663
  app.include_router(graphql_router)
538
664
  app.add_middleware(GZipMiddleware)
665
+ if authentication_enabled:
666
+ app.include_router(auth_router)
539
667
  if serve_ui:
540
668
  app.mount(
541
669
  "/",
@@ -554,8 +682,7 @@ def create_app(
554
682
  ),
555
683
  name="static",
556
684
  )
557
-
558
- app.state.db = db
685
+ app = _update_app_state(app, db=db, secret=secret)
559
686
  if tracer_provider:
560
687
  from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
561
688
 
@@ -563,3 +690,22 @@ def create_app(
563
690
  FastAPIInstrumentor.instrument_app(app, tracer_provider=tracer_provider)
564
691
  shutdown_callbacks_list.append(FastAPIInstrumentor().uninstrument)
565
692
  return app
693
+
694
+
695
+ def _update_app_state(app: FastAPI, /, *, db: DbSessionFactory, secret: Optional[str]) -> FastAPI:
696
+ """
697
+ Dynamically updates the app's `state` to include useful fields and methods
698
+ (at the time of this writing, FastAPI does not support setting this state
699
+ during the creation of the app).
700
+ """
701
+ app.state.db = db
702
+ app.state._secret = secret
703
+
704
+ def get_secret(self: StarletteState) -> str:
705
+ if (secret := self._secret) is None:
706
+ raise ValueError("app secret is not set")
707
+ assert isinstance(secret, str)
708
+ return secret
709
+
710
+ app.state.get_secret = MethodType(get_secret, app.state)
711
+ return app
phoenix/server/main.py CHANGED
@@ -48,6 +48,7 @@ from phoenix.trace.fixtures import (
48
48
  TRACES_FIXTURES,
49
49
  get_dataset_fixtures,
50
50
  get_evals_from_fixture,
51
+ get_trace_fixtures_by_project_name,
51
52
  load_example_traces,
52
53
  reset_fixture_span_ids_and_timestamps,
53
54
  send_dataset_fixtures,
@@ -135,7 +136,7 @@ if __name__ == "__main__":
135
136
  parser.add_argument("--export_path")
136
137
  parser.add_argument("--host", type=str, required=False)
137
138
  parser.add_argument("--port", type=int, required=False)
138
- parser.add_argument("--read-only", type=bool, default=False)
139
+ parser.add_argument("--read-only", action="store_true", required=False) # Default is False
139
140
  parser.add_argument("--no-internet", action="store_true")
140
141
  parser.add_argument("--umap_params", type=str, required=False, default=DEFAULT_UMAP_PARAMS_STR)
141
142
  parser.add_argument("--debug", action="store_true")
@@ -144,6 +145,43 @@ if __name__ == "__main__":
144
145
  parser.add_argument("--no-ui", action="store_true")
145
146
  subparsers = parser.add_subparsers(dest="command", required=True)
146
147
  serve_parser = subparsers.add_parser("serve")
148
+ serve_parser.add_argument(
149
+ "--with-fixture",
150
+ type=str,
151
+ required=False,
152
+ default="",
153
+ help=("Name of an inference fixture. Example: 'fixture1'"),
154
+ )
155
+ serve_parser.add_argument(
156
+ "--with-trace-fixtures",
157
+ type=str,
158
+ required=False,
159
+ default="",
160
+ help=(
161
+ "Comma separated list of tracing fixture names (spaces are ignored). "
162
+ "Example: 'fixture1, fixture2'"
163
+ ),
164
+ )
165
+ serve_parser.add_argument(
166
+ "--with-projects",
167
+ type=str,
168
+ required=False,
169
+ default="",
170
+ help=(
171
+ "Comma separated list of project names (spaces are ignored). "
172
+ "Example: 'project1, project2'"
173
+ ),
174
+ )
175
+ serve_parser.add_argument(
176
+ "--force-fixture-ingestion",
177
+ action="store_true", # default is False
178
+ required=False,
179
+ help=(
180
+ "Whether or not to check the database age before adding the fixtures. "
181
+ "Default is False, i.e., fixtures will only be added if the "
182
+ "database is new."
183
+ ),
184
+ )
147
185
  datasets_parser = subparsers.add_parser("datasets")
148
186
  datasets_parser.add_argument("--primary", type=str, required=True)
149
187
  datasets_parser.add_argument("--reference", type=str, required=False)
@@ -151,12 +189,14 @@ if __name__ == "__main__":
151
189
  datasets_parser.add_argument("--trace", type=str, required=False)
152
190
  fixture_parser = subparsers.add_parser("fixture")
153
191
  fixture_parser.add_argument("fixture", type=str, choices=[fixture.name for fixture in FIXTURES])
154
- fixture_parser.add_argument("--primary-only", type=bool)
192
+ fixture_parser.add_argument("--primary-only", action="store_true") # Default is False
155
193
  trace_fixture_parser = subparsers.add_parser("trace-fixture")
156
194
  trace_fixture_parser.add_argument(
157
195
  "fixture", type=str, choices=[fixture.name for fixture in TRACES_FIXTURES]
158
196
  )
159
- trace_fixture_parser.add_argument("--simulate-streaming", type=bool)
197
+ trace_fixture_parser.add_argument(
198
+ "--simulate-streaming", action="store_true"
199
+ ) # Default is False
160
200
  demo_parser = subparsers.add_parser("demo")
161
201
  demo_parser.add_argument("fixture", type=str, choices=[fixture.name for fixture in FIXTURES])
162
202
  demo_parser.add_argument(
@@ -164,10 +204,12 @@ if __name__ == "__main__":
164
204
  )
165
205
  demo_parser.add_argument("--simulate-streaming", action="store_true")
166
206
  args = parser.parse_args()
207
+
167
208
  db_connection_str = (
168
209
  args.database_url if args.database_url else get_env_database_connection_str()
169
210
  )
170
211
  export_path = Path(args.export_path) if args.export_path else EXPORT_DIR
212
+ force_fixture_ingestion = False
171
213
  if args.command == "datasets":
172
214
  primary_inferences_name = args.primary
173
215
  reference_inferences_name = args.reference
@@ -202,7 +244,26 @@ if __name__ == "__main__":
202
244
  )
203
245
  trace_dataset_name = args.trace_fixture
204
246
  simulate_streaming = args.simulate_streaming
205
-
247
+ elif args.command == "serve":
248
+ # We use sets to avoid duplicates
249
+ tracing_fixture_names = set()
250
+ if args.with_fixture:
251
+ primary_inferences, reference_inferences, corpus_inferences = get_inferences(
252
+ str(args.with_fixture),
253
+ args.no_internet,
254
+ )
255
+ if args.with_trace_fixtures:
256
+ tracing_fixture_names.update(
257
+ [name.strip() for name in args.with_trace_fixtures.split(",")]
258
+ )
259
+ if args.with_projects:
260
+ project_names = [name.strip() for name in args.with_projects.split(",")]
261
+ tracing_fixture_names.update(
262
+ fixture.name
263
+ for name in project_names
264
+ for fixture in get_trace_fixtures_by_project_name(name)
265
+ )
266
+ force_fixture_ingestion = args.force_fixture_ingestion
206
267
  host: Optional[str] = args.host or get_env_host()
207
268
  display_host = host or "localhost"
208
269
  # If the host is "::", the convention is to bind to all interfaces. However, uvicorn
@@ -260,6 +321,9 @@ if __name__ == "__main__":
260
321
  engine = create_engine_and_run_migrations(db_connection_str)
261
322
  instrumentation_cleanups = instrument_engine_if_enabled(engine)
262
323
  factory = DbSessionFactory(db=_db(engine), dialect=engine.dialect.name)
324
+ corpus_model = (
325
+ None if corpus_inferences is None else create_model_from_inferences(corpus_inferences)
326
+ )
263
327
  # Print information about the server
264
328
  msg = _WELCOME_MESSAGE.format(
265
329
  version=version("arize-phoenix"),
@@ -278,9 +342,7 @@ if __name__ == "__main__":
278
342
  model=model,
279
343
  authentication_enabled=authentication_enabled,
280
344
  umap_params=umap_params,
281
- corpus=None
282
- if corpus_inferences is None
283
- else create_model_from_inferences(corpus_inferences),
345
+ corpus=corpus_model,
284
346
  debug=args.debug,
285
347
  dev=args.dev,
286
348
  serve_ui=not args.no_ui,
@@ -291,6 +353,8 @@ if __name__ == "__main__":
291
353
  startup_callbacks=[lambda: print(msg)],
292
354
  shutdown_callbacks=instrumentation_cleanups,
293
355
  secret=secret,
356
+ tracing_fixture_names=tracing_fixture_names,
357
+ force_fixture_ingestion=force_fixture_ingestion,
294
358
  )
295
359
  server = Server(config=Config(app, host=host, port=port, root_path=host_root_path)) # type: ignore
296
360
  Thread(target=_write_pid_file_when_ready, args=(server,), daemon=True).start()
@@ -1,21 +1,21 @@
1
1
  {
2
- "_components-1Ahruijo.js": {
3
- "file": "assets/components-1Ahruijo.js",
2
+ "_components-1MfQimGx.js": {
3
+ "file": "assets/components-1MfQimGx.js",
4
4
  "name": "components",
5
5
  "imports": [
6
6
  "_vendor-aSQri0vz.js",
7
7
  "_vendor-arizeai-CsdcB1NH.js",
8
- "_pages-CFS6mPnW.js",
8
+ "_pages-CqZDVx20.js",
9
9
  "_vendor-three-DwGkEfCM.js",
10
10
  "_vendor-codemirror-CYHkhs7D.js"
11
11
  ]
12
12
  },
13
- "_pages-CFS6mPnW.js": {
14
- "file": "assets/pages-CFS6mPnW.js",
13
+ "_pages-CqZDVx20.js": {
14
+ "file": "assets/pages-CqZDVx20.js",
15
15
  "name": "pages",
16
16
  "imports": [
17
17
  "_vendor-aSQri0vz.js",
18
- "_components-1Ahruijo.js",
18
+ "_components-1MfQimGx.js",
19
19
  "_vendor-arizeai-CsdcB1NH.js",
20
20
  "_vendor-recharts-B0sannek.js",
21
21
  "_vendor-codemirror-CYHkhs7D.js"
@@ -61,15 +61,15 @@
61
61
  "name": "vendor-three"
62
62
  },
63
63
  "index.tsx": {
64
- "file": "assets/index-BEE_RWJx.js",
64
+ "file": "assets/index-B263sE2x.js",
65
65
  "name": "index",
66
66
  "src": "index.tsx",
67
67
  "isEntry": true,
68
68
  "imports": [
69
69
  "_vendor-aSQri0vz.js",
70
70
  "_vendor-arizeai-CsdcB1NH.js",
71
- "_pages-CFS6mPnW.js",
72
- "_components-1Ahruijo.js",
71
+ "_pages-CqZDVx20.js",
72
+ "_components-1MfQimGx.js",
73
73
  "_vendor-three-DwGkEfCM.js",
74
74
  "_vendor-recharts-B0sannek.js",
75
75
  "_vendor-codemirror-CYHkhs7D.js"
@@ -1,4 +1,4 @@
1
- import{c as je,p as Dt,d as qe,r as p,j as n,R as W,n as Fn,a as we,C as De,b as U,s as Et,e as Ft,f as ie,g as Se,h as Ke,i as Te,k as Le,l as Vt,m as _t,o as ae,q as Pt,t as Nt,u as Rt,v as s,w as m,x as Fe,$ as P,L as Vn,y as Ot,z as Kt,A as At,B as zt,D as cn,F as Ve,E as se,G as $t,H as Gt,I as _n,S as Bt,J as Qt,Q as dn,K as Ht,M as Ut,N as Zt,P as Ae,O as Pn,T as jt,U as qt,V as Wt,W as Jt,X as Xt,Y as Yt,Z as ea,_ as na,a0 as ta,a1 as We,a2 as Q,a3 as Nn,a4 as aa,a5 as ra,a6 as ia,a7 as la,a8 as oa}from"./vendor-aSQri0vz.js";import{u as sa,_ as q,a as _e,b as $,c as N,T as R,F as Rn,d as Z,I,e as w,f as G,A as ca,g as On,h as C,i as D,j as z,k as da,l as ua,P as ma,R as H,m as Pe,n as pa,o as ga,L as Je,p as J,q as X,r as Ne,s as ha,t as Kn,E as An,v as fa,w as La,x as ya,y as va,z as ba,B as Ca}from"./vendor-arizeai-CsdcB1NH.js";import{u as ka}from"./pages-CFS6mPnW.js";import{V as xa}from"./vendor-three-DwGkEfCM.js";import{j as zn,E as $n,l as Gn,a as Bn,R as Xe,n as Ye,p as wa}from"./vendor-codemirror-CYHkhs7D.js";const Sa=e=>{const t=a=>({markdownDisplayMode:"text",setMarkdownDisplayMode:r=>{a({markdownDisplayMode:r})},traceStreamingEnabled:!0,setTraceStreamingEnabled:r=>{a({traceStreamingEnabled:r})},showSpanAside:!0,setShowSpanAside:r=>{a({showSpanAside:r})},showMetricsInTraceTree:!0,setShowMetricsInTraceTree:r=>{a({showMetricsInTraceTree:r})},...e});return je()(Dt(qe(t),{name:"arize-phoenix-preferences"}))},Qn=p.createContext(null);function Rl({children:e,...t}){const a=p.useRef();return a.current||(a.current=Sa(t)),n(Qn.Provider,{value:a.current,children:e})}function be(e,t){const a=W.useContext(Qn);if(!a)throw new Error("Missing PreferencesContext.Provider in the tree");return Fn(a,e,t)}var A=(e=>(e.primary="primary",e.reference="reference",e.corpus="corpus",e))(A||{});function V(e){throw new Error("Unreachable")}function en(e){return typeof e=="number"||e===null}function Ma(e){return typeof e=="string"||e===null}function Ol(e){return Array.isArray(e)?e.every(t=>typeof t=="string"):!1}function Ta(e){return typeof e=="object"&&e!==null}const nn=p.createContext(null);function Re(){const e=W.useContext(nn);if(e===null)throw new Error("useInferences must be used within a InferencesProvider");return e}function Kl(e){return n(nn.Provider,{value:{primaryInferences:e.primaryInferences,referenceInferences:e.referenceInferences,corpusInferences:e.corpusInferences,getInferencesNameByRole:t=>{var a,r;switch(t){case A.primary:return e.primaryInferences.name;case A.reference:return((a=e.referenceInferences)==null?void 0:a.name)??"reference";case A.corpus:return((r=e.corpusInferences)==null?void 0:r.name)??"corpus";default:V()}}},children:e.children})}const Hn=function(){var e={defaultValue:null,kind:"LocalArgument",name:"clusters"},t={defaultValue:null,kind:"LocalArgument",name:"dataQualityMetricColumnName"},a={defaultValue:null,kind:"LocalArgument",name:"fetchDataQualityMetric"},r={defaultValue:null,kind:"LocalArgument",name:"fetchPerformanceMetric"},i={defaultValue:null,kind:"LocalArgument",name:"performanceMetric"},l=[{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:l,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:l,storageKey:null}]}],storageKey:null}];return{fragment:{argumentDefinitions:[e,t,a,r,i],kind:"Fragment",metadata:null,name:"pointCloudStore_clusterMetricsQuery",selections:o,type:"Query",abstractKey:null},kind:"Request",operation:{argumentDefinitions:[e,a,t,r,i],kind:"Operation",name:"pointCloudStore_clusterMetricsQuery",selections:o},params:{cacheID:"86666967012812887ac0a0149d2d2535",id:null,metadata:{},name:"pointCloudStore_clusterMetricsQuery",operationKind:"query",text:`query pointCloudStore_clusterMetricsQuery(
1
+ import{c as je,p as Dt,d as qe,r as p,j as n,R as W,n as Fn,a as we,C as De,b as U,s as Et,e as Ft,f as ie,g as Se,h as Ke,i as Te,k as Le,l as Vt,m as _t,o as ae,q as Pt,t as Nt,u as Rt,v as s,w as m,x as Fe,$ as P,L as Vn,y as Ot,z as Kt,A as At,B as zt,D as cn,F as Ve,E as se,G as $t,H as Gt,I as _n,S as Bt,J as Qt,Q as dn,K as Ht,M as Ut,N as Zt,P as Ae,O as Pn,T as jt,U as qt,V as Wt,W as Jt,X as Xt,Y as Yt,Z as ea,_ as na,a0 as ta,a1 as We,a2 as Q,a3 as Nn,a4 as aa,a5 as ra,a6 as ia,a7 as la,a8 as oa}from"./vendor-aSQri0vz.js";import{u as sa,_ as q,a as _e,b as $,c as N,T as R,F as Rn,d as Z,I,e as w,f as G,A as ca,g as On,h as C,i as D,j as z,k as da,l as ua,P as ma,R as H,m as Pe,n as pa,o as ga,L as Je,p as J,q as X,r as Ne,s as ha,t as Kn,E as An,v as fa,w as La,x as ya,y as va,z as ba,B as Ca}from"./vendor-arizeai-CsdcB1NH.js";import{u as ka}from"./pages-CqZDVx20.js";import{V as xa}from"./vendor-three-DwGkEfCM.js";import{j as zn,E as $n,l as Gn,a as Bn,R as Xe,n as Ye,p as wa}from"./vendor-codemirror-CYHkhs7D.js";const Sa=e=>{const t=a=>({markdownDisplayMode:"text",setMarkdownDisplayMode:r=>{a({markdownDisplayMode:r})},traceStreamingEnabled:!0,setTraceStreamingEnabled:r=>{a({traceStreamingEnabled:r})},showSpanAside:!0,setShowSpanAside:r=>{a({showSpanAside:r})},showMetricsInTraceTree:!0,setShowMetricsInTraceTree:r=>{a({showMetricsInTraceTree:r})},...e});return je()(Dt(qe(t),{name:"arize-phoenix-preferences"}))},Qn=p.createContext(null);function Rl({children:e,...t}){const a=p.useRef();return a.current||(a.current=Sa(t)),n(Qn.Provider,{value:a.current,children:e})}function be(e,t){const a=W.useContext(Qn);if(!a)throw new Error("Missing PreferencesContext.Provider in the tree");return Fn(a,e,t)}var A=(e=>(e.primary="primary",e.reference="reference",e.corpus="corpus",e))(A||{});function V(e){throw new Error("Unreachable")}function en(e){return typeof e=="number"||e===null}function Ma(e){return typeof e=="string"||e===null}function Ol(e){return Array.isArray(e)?e.every(t=>typeof t=="string"):!1}function Ta(e){return typeof e=="object"&&e!==null}const nn=p.createContext(null);function Re(){const e=W.useContext(nn);if(e===null)throw new Error("useInferences must be used within a InferencesProvider");return e}function Kl(e){return n(nn.Provider,{value:{primaryInferences:e.primaryInferences,referenceInferences:e.referenceInferences,corpusInferences:e.corpusInferences,getInferencesNameByRole:t=>{var a,r;switch(t){case A.primary:return e.primaryInferences.name;case A.reference:return((a=e.referenceInferences)==null?void 0:a.name)??"reference";case A.corpus:return((r=e.corpusInferences)==null?void 0:r.name)??"corpus";default:V()}}},children:e.children})}const Hn=function(){var e={defaultValue:null,kind:"LocalArgument",name:"clusters"},t={defaultValue:null,kind:"LocalArgument",name:"dataQualityMetricColumnName"},a={defaultValue:null,kind:"LocalArgument",name:"fetchDataQualityMetric"},r={defaultValue:null,kind:"LocalArgument",name:"fetchPerformanceMetric"},i={defaultValue:null,kind:"LocalArgument",name:"performanceMetric"},l=[{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:l,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:l,storageKey:null}]}],storageKey:null}];return{fragment:{argumentDefinitions:[e,t,a,r,i],kind:"Fragment",metadata:null,name:"pointCloudStore_clusterMetricsQuery",selections:o,type:"Query",abstractKey:null},kind:"Request",operation:{argumentDefinitions:[e,a,t,r,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
@@ -1064,7 +1064,7 @@ fragment ModelEmbeddingsTable_embeddingDimensions_4sIU9C on Query {
1064
1064
  &:hover {
1065
1065
  color: var(--ac-global-color-primary);
1066
1066
  }
1067
- `,children:n(I,{svg:e.isExpanded?n(w.ChevronDownOutline,{}):n(w.ChevronRightOutline,{})})})}function wl(){return s("svg",{xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",viewBox:"0 0 305.92 350.13",width:28,height:28,css:m`
1067
+ `,children:n(I,{svg:e.isExpanded?n(w.ChevronDownOutline,{}):n(w.ChevronRightOutline,{})})})}function wl(e){const{size:t=28}=e;return s("svg",{xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",viewBox:"0 0 305.92 350.13",width:t,height:t,css:m`
1068
1068
  .cls-1 {
1069
1069
  fill: url(#linear-gradient);
1070
1070
  }
@@ -1217,4 +1217,4 @@ fragment ModelEmbeddingsTable_embeddingDimensions_4sIU9C on Query {
1217
1217
  right: var(--ac-global-dimension-size-100);
1218
1218
  z-index: 1;
1219
1219
  }
1220
- `,children:[n(mr,{text:t}),n(Ll,{value:t})]})}function to({sequenceNumber:e}){return s(Je,{color:"yellow-1000",children:["#",e]})}export{g1 as $,pe as A,e1 as B,v1 as C,Ra as D,E1 as E,ve as F,gt as G,de as H,D1 as I,m1 as J,an as K,dr as L,o1 as M,p1 as N,h1 as O,Wl as P,$l as Q,xe as R,re as S,ql as T,zl as U,Gl as V,Bl as W,s1 as X,f1 as Y,i1 as Z,u1 as _,qa as a,ar as a$,L1 as a0,d1 as a1,er as a2,x1 as a3,I1 as a4,dt as a5,nr as a6,l1 as a7,me as a8,Ei as a9,c1 as aA,Ul as aB,Yl as aC,B1 as aD,lt as aE,Q1 as aF,rl as aG,H1 as aH,G1 as aI,Y1 as aJ,W1 as aK,q1 as aL,X1 as aM,Z1 as aN,U1 as aO,j1 as aP,J1 as aQ,Ql as aR,Kl as aS,$1 as aT,eo as aU,t1 as aV,no as aW,Ka as aX,A1 as aY,Di as aZ,to as a_,Ti as aa,Zl as ab,_i as ac,Pi as ad,Vi as ae,Ni as af,F1 as ag,mr as ah,Xa as ai,n1 as aj,z1 as ak,Cl as al,fl as am,be as an,K1 as ao,P1 as ap,Ol as aq,tl as ar,N1 as as,O1 as at,R1 as au,_1 as av,V1 as aw,kl as ax,Ii as ay,Ya as az,Jl as b,or as b0,Xl as b1,Al as b2,jl as b3,Rl as b4,Hl as b5,a1 as c,B as d,Na as e,y as f,nt as g,V as h,pr as i,w1 as j,S1 as k,M1 as l,C1 as m,k1 as n,T1 as o,Ue as p,b1 as q,y1 as r,Cn as s,ot as t,Re as u,Dr as v,Er as w,qn as x,Rr as y,r1 as z};
1220
+ `,children:[n(mr,{text:t}),n(Ll,{value:t})]})}function to({sequenceNumber:e}){return s(Je,{color:"yellow-1000",children:["#",e]})}export{g1 as $,pe as A,e1 as B,v1 as C,Ra as D,E1 as E,ve as F,gt as G,de as H,D1 as I,m1 as J,an as K,dr as L,o1 as M,p1 as N,h1 as O,Wl as P,$l as Q,xe as R,re as S,ql as T,zl as U,Gl as V,Bl as W,s1 as X,f1 as Y,i1 as Z,u1 as _,qa as a,ar as a$,L1 as a0,d1 as a1,er as a2,x1 as a3,I1 as a4,dt as a5,nr as a6,l1 as a7,me as a8,Ei as a9,c1 as aA,Ul as aB,Yl as aC,B1 as aD,lt as aE,Q1 as aF,rl as aG,H1 as aH,G1 as aI,Y1 as aJ,W1 as aK,q1 as aL,X1 as aM,Z1 as aN,U1 as aO,j1 as aP,J1 as aQ,Ql as aR,Kl as aS,$1 as aT,eo as aU,t1 as aV,no as aW,Ka as aX,A1 as aY,Di as aZ,to as a_,Ti as aa,Zl as ab,_i as ac,Pi as ad,Vi as ae,Ni as af,F1 as ag,mr as ah,Xa as ai,n1 as aj,z1 as ak,Cl as al,fl as am,be as an,K1 as ao,P1 as ap,Ol as aq,tl as ar,N1 as as,O1 as at,R1 as au,_1 as av,V1 as aw,kl as ax,Ii as ay,Ya as az,Jl as b,or as b0,Xl as b1,Al as b2,wl as b3,jl as b4,Rl as b5,Hl as b6,a1 as c,B as d,Na as e,y as f,nt as g,V as h,pr as i,w1 as j,S1 as k,M1 as l,C1 as m,k1 as n,T1 as o,Ue as p,b1 as q,y1 as r,Cn as s,ot as t,Re as u,Dr as v,Er as w,qn as x,Rr as y,r1 as z};