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

Files changed (39) hide show
  1. {arize_phoenix-5.6.0.dist-info → arize_phoenix-5.8.0.dist-info}/METADATA +4 -6
  2. {arize_phoenix-5.6.0.dist-info → arize_phoenix-5.8.0.dist-info}/RECORD +39 -30
  3. {arize_phoenix-5.6.0.dist-info → arize_phoenix-5.8.0.dist-info}/WHEEL +1 -1
  4. phoenix/config.py +58 -0
  5. phoenix/server/api/helpers/playground_clients.py +758 -0
  6. phoenix/server/api/helpers/playground_registry.py +70 -0
  7. phoenix/server/api/helpers/playground_spans.py +422 -0
  8. phoenix/server/api/input_types/ChatCompletionInput.py +38 -0
  9. phoenix/server/api/input_types/GenerativeModelInput.py +17 -0
  10. phoenix/server/api/input_types/InvocationParameters.py +155 -13
  11. phoenix/server/api/input_types/TemplateOptions.py +10 -0
  12. phoenix/server/api/mutations/__init__.py +4 -0
  13. phoenix/server/api/mutations/chat_mutations.py +355 -0
  14. phoenix/server/api/queries.py +41 -52
  15. phoenix/server/api/schema.py +42 -10
  16. phoenix/server/api/subscriptions.py +378 -595
  17. phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +46 -0
  18. phoenix/server/api/types/GenerativeProvider.py +27 -3
  19. phoenix/server/api/types/Span.py +37 -0
  20. phoenix/server/api/types/TemplateLanguage.py +9 -0
  21. phoenix/server/app.py +75 -13
  22. phoenix/server/grpc_server.py +3 -1
  23. phoenix/server/main.py +14 -1
  24. phoenix/server/static/.vite/manifest.json +31 -31
  25. phoenix/server/static/assets/{components-C70HJiXz.js → components-MllbfxfJ.js} +168 -150
  26. phoenix/server/static/assets/{index-DLe1Oo3l.js → index-BVO2YcT1.js} +2 -2
  27. phoenix/server/static/assets/{pages-C8-Sl7JI.js → pages-BHfC6jnL.js} +464 -310
  28. phoenix/server/static/assets/{vendor-CtqfhlbC.js → vendor-BEuNhfwH.js} +1 -1
  29. phoenix/server/static/assets/{vendor-arizeai-C_3SBz56.js → vendor-arizeai-Bskhzyjm.js} +1 -1
  30. phoenix/server/static/assets/{vendor-codemirror-wfdk9cjp.js → vendor-codemirror-DLlXCf0x.js} +1 -1
  31. phoenix/server/static/assets/{vendor-recharts-BiVnSv90.js → vendor-recharts-CRqhvLYg.js} +1 -1
  32. phoenix/server/templates/index.html +1 -0
  33. phoenix/services.py +4 -0
  34. phoenix/session/session.py +15 -1
  35. phoenix/utilities/template_formatters.py +11 -1
  36. phoenix/version.py +1 -1
  37. {arize_phoenix-5.6.0.dist-info → arize_phoenix-5.8.0.dist-info}/entry_points.txt +0 -0
  38. {arize_phoenix-5.6.0.dist-info → arize_phoenix-5.8.0.dist-info}/licenses/IP_NOTICE +0 -0
  39. {arize_phoenix-5.6.0.dist-info → arize_phoenix-5.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,46 @@
1
+ from typing import Optional
2
+
3
+ import strawberry
4
+ from strawberry.relay import GlobalID
5
+
6
+ from .Experiment import Experiment
7
+ from .ExperimentRun import ExperimentRun
8
+ from .Span import Span
9
+
10
+
11
+ @strawberry.interface
12
+ class ChatCompletionSubscriptionPayload:
13
+ dataset_example_id: Optional[GlobalID] = None
14
+
15
+
16
+ @strawberry.type
17
+ class TextChunk(ChatCompletionSubscriptionPayload):
18
+ content: str
19
+
20
+
21
+ @strawberry.type
22
+ class FunctionCallChunk(ChatCompletionSubscriptionPayload):
23
+ name: str
24
+ arguments: str
25
+
26
+
27
+ @strawberry.type
28
+ class ToolCallChunk(ChatCompletionSubscriptionPayload):
29
+ id: str
30
+ function: FunctionCallChunk
31
+
32
+
33
+ @strawberry.type
34
+ class ChatCompletionSubscriptionResult(ChatCompletionSubscriptionPayload):
35
+ span: Optional[Span] = None
36
+ experiment_run: Optional[ExperimentRun] = None
37
+
38
+
39
+ @strawberry.type
40
+ class ChatCompletionSubscriptionError(ChatCompletionSubscriptionPayload):
41
+ message: str
42
+
43
+
44
+ @strawberry.type
45
+ class ChatCompletionSubscriptionExperiment(ChatCompletionSubscriptionPayload):
46
+ experiment: Experiment
@@ -5,12 +5,36 @@ import strawberry
5
5
 
6
6
  @strawberry.enum
7
7
  class GenerativeProviderKey(Enum):
8
- OPENAI = "OPENAI"
9
- ANTHROPIC = "ANTHROPIC"
10
- AZURE_OPENAI = "AZURE_OPENAI"
8
+ OPENAI = "OpenAI"
9
+ ANTHROPIC = "Anthropic"
10
+ AZURE_OPENAI = "Azure OpenAI"
11
11
 
12
12
 
13
13
  @strawberry.type
14
14
  class GenerativeProvider:
15
15
  name: str
16
16
  key: GenerativeProviderKey
17
+
18
+ @strawberry.field
19
+ async def dependencies(self) -> list[str]:
20
+ from phoenix.server.api.helpers.playground_registry import (
21
+ PLAYGROUND_CLIENT_REGISTRY,
22
+ PROVIDER_DEFAULT,
23
+ )
24
+
25
+ default_client = PLAYGROUND_CLIENT_REGISTRY.get_client(self.key, PROVIDER_DEFAULT)
26
+ if default_client:
27
+ return default_client.dependencies()
28
+ return []
29
+
30
+ @strawberry.field
31
+ async def dependencies_installed(self) -> bool:
32
+ from phoenix.server.api.helpers.playground_registry import (
33
+ PLAYGROUND_CLIENT_REGISTRY,
34
+ PROVIDER_DEFAULT,
35
+ )
36
+
37
+ default_client = PLAYGROUND_CLIENT_REGISTRY.get_client(self.key, PROVIDER_DEFAULT)
38
+ if default_client:
39
+ return default_client.dependencies_are_installed()
40
+ return False
@@ -20,10 +20,12 @@ from phoenix.server.api.helpers.dataset_helpers import (
20
20
  get_dataset_example_input,
21
21
  get_dataset_example_output,
22
22
  )
23
+ from phoenix.server.api.input_types.InvocationParameters import InvocationParameter
23
24
  from phoenix.server.api.input_types.SpanAnnotationSort import (
24
25
  SpanAnnotationColumn,
25
26
  SpanAnnotationSort,
26
27
  )
28
+ from phoenix.server.api.types.GenerativeProvider import GenerativeProviderKey
27
29
  from phoenix.server.api.types.SortDir import SortDir
28
30
  from phoenix.server.api.types.SpanAnnotation import to_gql_span_annotation
29
31
  from phoenix.trace.attributes import get_attribute_value
@@ -291,6 +293,41 @@ class Span(Node):
291
293
  examples = await info.context.data_loaders.span_dataset_examples.load(self.id_attr)
292
294
  return bool(examples)
293
295
 
296
+ @strawberry.field(description="Invocation parameters for the span") # type: ignore
297
+ async def invocation_parameters(self, info: Info[Context, None]) -> list[InvocationParameter]:
298
+ from phoenix.server.api.helpers.playground_clients import OpenAIStreamingClient
299
+ from phoenix.server.api.helpers.playground_registry import PLAYGROUND_CLIENT_REGISTRY
300
+
301
+ db_span = self.db_span
302
+ attributes = db_span.attributes
303
+ llm_provider: GenerativeProviderKey = (
304
+ get_attribute_value(attributes, SpanAttributes.LLM_PROVIDER)
305
+ or GenerativeProviderKey.OPENAI
306
+ )
307
+ llm_model = get_attribute_value(attributes, SpanAttributes.LLM_MODEL_NAME)
308
+ invocation_parameters = get_attribute_value(
309
+ attributes, SpanAttributes.LLM_INVOCATION_PARAMETERS
310
+ )
311
+ if invocation_parameters is None:
312
+ return []
313
+ invocation_parameters = json.loads(invocation_parameters)
314
+ # find the client class for the provider, if there is no client class or provider,
315
+ # return openai as default
316
+ client_class = PLAYGROUND_CLIENT_REGISTRY.get_client(llm_provider, llm_model)
317
+ if not client_class:
318
+ client_class = OpenAIStreamingClient
319
+ supported_invocation_parameters = client_class.supported_invocation_parameters()
320
+ # filter supported invocation parameters down to those whose canonical_name is in the
321
+ # invocation_parameters keys
322
+ return [
323
+ ip
324
+ for ip in supported_invocation_parameters
325
+ if (
326
+ ip.canonical_name in invocation_parameters
327
+ or ip.invocation_name in invocation_parameters
328
+ )
329
+ ]
330
+
294
331
 
295
332
  def to_gql_span(span: models.Span) -> Span:
296
333
  events: list[SpanEvent] = list(map(SpanEvent.from_dict, span.events))
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+ import strawberry
4
+
5
+
6
+ @strawberry.enum
7
+ class TemplateLanguage(Enum):
8
+ MUSTACHE = "MUSTACHE"
9
+ F_STRING = "F_STRING"
phoenix/server/app.py CHANGED
@@ -1,7 +1,9 @@
1
1
  import asyncio
2
2
  import contextlib
3
+ import importlib
3
4
  import json
4
5
  import logging
6
+ import os
5
7
  from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence
6
8
  from contextlib import AbstractAsyncContextManager, AsyncExitStack
7
9
  from dataclasses import dataclass, field
@@ -24,6 +26,7 @@ import strawberry
24
26
  from fastapi import APIRouter, Depends, FastAPI
25
27
  from fastapi.middleware.gzip import GZipMiddleware
26
28
  from fastapi.utils import is_body_allowed_for_status_code
29
+ from grpc.aio import ServerInterceptor
27
30
  from sqlalchemy import select
28
31
  from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
29
32
  from starlette.datastructures import State as StarletteState
@@ -40,7 +43,6 @@ from starlette.types import Scope, StatefulLifespan
40
43
  from starlette.websockets import WebSocket
41
44
  from strawberry.extensions import SchemaExtension
42
45
  from strawberry.fastapi import GraphQLRouter
43
- from strawberry.schema import BaseSchema
44
46
  from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL
45
47
  from typing_extensions import TypeAlias
46
48
 
@@ -51,6 +53,9 @@ from phoenix.config import (
51
53
  SERVER_DIR,
52
54
  OAuth2ClientConfig,
53
55
  get_env_csrf_trusted_origins,
56
+ get_env_fastapi_middleware_paths,
57
+ get_env_gql_extension_paths,
58
+ get_env_grpc_interceptor_paths,
54
59
  get_env_host,
55
60
  get_env_port,
56
61
  server_instrumentation_is_enabled,
@@ -98,7 +103,7 @@ from phoenix.server.api.routers import (
98
103
  oauth2_router,
99
104
  )
100
105
  from phoenix.server.api.routers.v1 import REST_API_VERSION
101
- from phoenix.server.api.schema import schema
106
+ from phoenix.server.api.schema import build_graphql_schema
102
107
  from phoenix.server.bearer_auth import BearerTokenAuthBackend, is_authenticated
103
108
  from phoenix.server.dml_event import DmlEvent
104
109
  from phoenix.server.dml_event_handler import DmlEventHandler
@@ -150,6 +155,28 @@ ProjectName: TypeAlias = str
150
155
  _Callback: TypeAlias = Callable[[], Union[None, Awaitable[None]]]
151
156
 
152
157
 
158
+ def import_object_from_file(file_path: str, object_name: str) -> Any:
159
+ """Import an object (class or function) from a Python file."""
160
+ try:
161
+ if not os.path.isfile(file_path):
162
+ raise FileNotFoundError(f"File '{file_path}' does not exist.")
163
+ module_name = f"custom_module_{hash(file_path)}"
164
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
165
+ if spec is None:
166
+ raise ImportError(f"Could not load spec for '{file_path}'")
167
+ module = importlib.util.module_from_spec(spec)
168
+ loader = spec.loader
169
+ if loader is None:
170
+ raise ImportError(f"No loader found for '{file_path}'")
171
+ loader.exec_module(module)
172
+ try:
173
+ return getattr(module, object_name)
174
+ except AttributeError:
175
+ raise ImportError(f"Module '{file_path}' does not have an object '{object_name}'.")
176
+ except Exception as e:
177
+ raise ImportError(f"Could not import '{object_name}' from '{file_path}': {e}")
178
+
179
+
153
180
  class OAuth2Idp(TypedDict):
154
181
  name: str
155
182
  displayName: str
@@ -166,6 +193,7 @@ class AppConfig(NamedTuple):
166
193
  web_manifest_path: Path
167
194
  authentication_enabled: bool
168
195
  """ Whether authentication is enabled """
196
+ websockets_enabled: bool
169
197
  oauth2_idps: Sequence[OAuth2Idp]
170
198
 
171
199
 
@@ -216,6 +244,7 @@ class Static(StaticFiles):
216
244
  "manifest": self._web_manifest,
217
245
  "authentication_enabled": self._app_config.authentication_enabled,
218
246
  "oauth2_idps": self._app_config.oauth2_idps,
247
+ "websockets_enabled": self._app_config.websockets_enabled,
219
248
  },
220
249
  )
221
250
  except Exception as e:
@@ -256,6 +285,39 @@ class HeadersMiddleware(BaseHTTPMiddleware):
256
285
  return response
257
286
 
258
287
 
288
+ def user_fastapi_middlewares() -> list[Middleware]:
289
+ paths = get_env_fastapi_middleware_paths()
290
+ middlewares = []
291
+ for file_path, object_name in paths:
292
+ middleware_class = import_object_from_file(file_path, object_name)
293
+ if not issubclass(middleware_class, BaseHTTPMiddleware):
294
+ raise TypeError(f"{middleware_class} is not a subclass of BaseHTTPMiddleware")
295
+ middlewares.append(Middleware(middleware_class))
296
+ return middlewares
297
+
298
+
299
+ def user_gql_extensions() -> list[Union[type[SchemaExtension], SchemaExtension]]:
300
+ paths = get_env_gql_extension_paths()
301
+ extensions = []
302
+ for file_path, object_name in paths:
303
+ extension_class = import_object_from_file(file_path, object_name)
304
+ if not issubclass(extension_class, SchemaExtension):
305
+ raise TypeError(f"{extension_class} is not a subclass of SchemaExtension")
306
+ extensions.append(extension_class)
307
+ return extensions
308
+
309
+
310
+ def user_grpc_interceptors() -> list[ServerInterceptor]:
311
+ paths = get_env_grpc_interceptor_paths()
312
+ interceptors = []
313
+ for file_path, object_name in paths:
314
+ interceptor_class = import_object_from_file(file_path, object_name)
315
+ if not issubclass(interceptor_class, ServerInterceptor):
316
+ raise TypeError(f"{interceptor_class} is not a subclass of ServerInterceptor")
317
+ interceptors.append(interceptor_class)
318
+ return interceptors
319
+
320
+
259
321
  ProjectRowId: TypeAlias = int
260
322
 
261
323
 
@@ -430,6 +492,7 @@ def _lifespan(
430
492
  tracer_provider=tracer_provider,
431
493
  enable_prometheus=enable_prometheus,
432
494
  token_store=token_store,
495
+ interceptors=user_grpc_interceptors(),
433
496
  )
434
497
  await stack.enter_async_context(grpc_server)
435
498
  await stack.enter_async_context(dml_event_handler)
@@ -463,7 +526,7 @@ async def check_healthz(_: Request) -> PlainTextResponse:
463
526
 
464
527
  def create_graphql_router(
465
528
  *,
466
- schema: BaseSchema,
529
+ graphql_schema: strawberry.Schema,
467
530
  db: DbSessionFactory,
468
531
  model: Model,
469
532
  export_path: Path,
@@ -567,7 +630,7 @@ def create_graphql_router(
567
630
  )
568
631
 
569
632
  return GraphQLRouter(
570
- schema,
633
+ graphql_schema,
571
634
  graphql_ide="graphiql",
572
635
  context_getter=get_context,
573
636
  include_in_schema=False,
@@ -653,6 +716,7 @@ def create_app(
653
716
  model: Model,
654
717
  authentication_enabled: bool,
655
718
  umap_params: UMAPParameters,
719
+ enable_websockets: bool,
656
720
  corpus: Optional[Model] = None,
657
721
  debug: bool = False,
658
722
  dev: bool = False,
@@ -700,6 +764,7 @@ def create_app(
700
764
  )
701
765
  last_updated_at = LastUpdatedAt()
702
766
  middlewares: list[Middleware] = [Middleware(HeadersMiddleware)]
767
+ middlewares.extend(user_fastapi_middlewares())
703
768
  if origins := get_env_csrf_trusted_origins():
704
769
  trusted_hostnames = [h for o in origins if o and (h := urlparse(o).hostname)]
705
770
  middlewares.append(Middleware(RequestOriginHostnameValidator, trusted_hostnames))
@@ -733,8 +798,9 @@ def create_app(
733
798
  initial_batch_of_evaluations=initial_batch_of_evaluations,
734
799
  )
735
800
  tracer_provider = None
736
- strawberry_extensions: list[Union[type[SchemaExtension], SchemaExtension]] = []
737
- strawberry_extensions.extend(schema.get_extensions())
801
+ graphql_schema_extensions: list[Union[type[SchemaExtension], SchemaExtension]] = []
802
+ graphql_schema_extensions.extend(user_gql_extensions())
803
+
738
804
  if server_instrumentation_is_enabled():
739
805
  tracer_provider = initialize_opentelemetry_tracer_provider()
740
806
  from opentelemetry.trace import TracerProvider
@@ -752,16 +818,11 @@ def create_app(
752
818
  # used by OpenInference.
753
819
  self._tracer = cast(TracerProvider, tracer_provider).get_tracer("strawberry")
754
820
 
755
- strawberry_extensions.append(_OpenTelemetryExtension)
821
+ graphql_schema_extensions.append(_OpenTelemetryExtension)
756
822
 
757
823
  graphql_router = create_graphql_router(
758
824
  db=db,
759
- schema=strawberry.Schema(
760
- query=schema.query,
761
- mutation=schema.mutation,
762
- subscription=schema.subscription,
763
- extensions=strawberry_extensions,
764
- ),
825
+ graphql_schema=build_graphql_schema(graphql_schema_extensions),
765
826
  model=model,
766
827
  corpus=corpus,
767
828
  authentication_enabled=authentication_enabled,
@@ -830,6 +891,7 @@ def create_app(
830
891
  authentication_enabled=authentication_enabled,
831
892
  web_manifest_path=web_manifest_path,
832
893
  oauth2_idps=oauth2_idps,
894
+ websockets_enabled=enable_websockets,
833
895
  ),
834
896
  ),
835
897
  name="static",
@@ -56,6 +56,7 @@ class GrpcServer:
56
56
  enable_prometheus: bool = False,
57
57
  disabled: bool = False,
58
58
  token_store: Optional[CanReadToken] = None,
59
+ interceptors: list[ServerInterceptor] = [],
59
60
  ) -> None:
60
61
  self._callback = callback
61
62
  self._server: Optional[Server] = None
@@ -63,11 +64,12 @@ class GrpcServer:
63
64
  self._enable_prometheus = enable_prometheus
64
65
  self._disabled = disabled
65
66
  self._token_store = token_store
67
+ self._interceptors = interceptors
66
68
 
67
69
  async def __aenter__(self) -> None:
70
+ interceptors = self._interceptors
68
71
  if self._disabled:
69
72
  return
70
- interceptors: list[ServerInterceptor] = []
71
73
  if self._token_store:
72
74
  interceptors.append(ApiKeyInterceptor(self._token_store))
73
75
  if self._enable_prometheus:
phoenix/server/main.py CHANGED
@@ -21,6 +21,7 @@ from phoenix.config import (
21
21
  get_env_database_schema,
22
22
  get_env_db_logging_level,
23
23
  get_env_enable_prometheus,
24
+ get_env_enable_websockets,
24
25
  get_env_grpc_port,
25
26
  get_env_host,
26
27
  get_env_host_root_path,
@@ -95,6 +96,7 @@ _WELCOME_MESSAGE = Environment(loader=BaseLoader()).from_string("""
95
96
  | 🚀 Phoenix Server 🚀
96
97
  | Phoenix UI: {{ ui_path }}
97
98
  | Authentication: {{ auth_enabled }}
99
+ | Websockets: {{ websockets_enabled }}
98
100
  | Log traces:
99
101
  | - gRPC: {{ grpc_path }}
100
102
  | - HTTP: {{ http_path }}
@@ -162,7 +164,7 @@ def main() -> None:
162
164
  parser.add_argument("--debug", action="store_true", help=SUPPRESS)
163
165
  parser.add_argument("--dev", action="store_true", help=SUPPRESS)
164
166
  parser.add_argument("--no-ui", action="store_true", help=SUPPRESS)
165
-
167
+ parser.add_argument("--enable-websockets", type=str, help=SUPPRESS)
166
168
  subparsers = parser.add_subparsers(dest="command", required=True, help=SUPPRESS)
167
169
 
168
170
  serve_parser = subparsers.add_parser("serve")
@@ -348,6 +350,14 @@ def main() -> None:
348
350
  corpus_model = (
349
351
  None if corpus_inferences is None else create_model_from_inferences(corpus_inferences)
350
352
  )
353
+
354
+ # Get enable_websockets from environment variable or command line argument
355
+ enable_websockets = get_env_enable_websockets()
356
+ if args.enable_websockets is not None:
357
+ enable_websockets = args.enable_websockets.lower() == "true"
358
+ if enable_websockets is None:
359
+ enable_websockets = True
360
+
351
361
  # Print information about the server
352
362
  root_path = urljoin(f"http://{host}:{port}", host_root_path)
353
363
  msg = _WELCOME_MESSAGE.render(
@@ -358,6 +368,7 @@ def main() -> None:
358
368
  storage=get_printable_db_url(db_connection_str),
359
369
  schema=get_env_database_schema(),
360
370
  auth_enabled=authentication_enabled,
371
+ websockets_enabled=enable_websockets,
361
372
  )
362
373
  if sys.platform.startswith("win"):
363
374
  msg = codecs.encode(msg, "ascii", errors="ignore").decode("ascii").strip()
@@ -382,10 +393,12 @@ def main() -> None:
382
393
  connection_method="STARTTLS",
383
394
  validate_certs=get_env_smtp_validate_certs(),
384
395
  )
396
+
385
397
  app = create_app(
386
398
  db=factory,
387
399
  export_path=export_path,
388
400
  model=model,
401
+ enable_websockets=enable_websockets,
389
402
  authentication_enabled=authentication_enabled,
390
403
  umap_params=umap_params,
391
404
  corpus=corpus_model,
@@ -1,32 +1,32 @@
1
1
  {
2
- "_components-C70HJiXz.js": {
3
- "file": "assets/components-C70HJiXz.js",
2
+ "_components-MllbfxfJ.js": {
3
+ "file": "assets/components-MllbfxfJ.js",
4
4
  "name": "components",
5
5
  "imports": [
6
- "_vendor-CtqfhlbC.js",
7
- "_vendor-arizeai-C_3SBz56.js",
8
- "_pages-C8-Sl7JI.js",
6
+ "_vendor-BEuNhfwH.js",
7
+ "_vendor-arizeai-Bskhzyjm.js",
8
+ "_pages-BHfC6jnL.js",
9
9
  "_vendor-three-DwGkEfCM.js",
10
- "_vendor-codemirror-wfdk9cjp.js"
10
+ "_vendor-codemirror-DLlXCf0x.js"
11
11
  ]
12
12
  },
13
- "_pages-C8-Sl7JI.js": {
14
- "file": "assets/pages-C8-Sl7JI.js",
13
+ "_pages-BHfC6jnL.js": {
14
+ "file": "assets/pages-BHfC6jnL.js",
15
15
  "name": "pages",
16
16
  "imports": [
17
- "_vendor-CtqfhlbC.js",
18
- "_vendor-arizeai-C_3SBz56.js",
19
- "_components-C70HJiXz.js",
20
- "_vendor-recharts-BiVnSv90.js",
21
- "_vendor-codemirror-wfdk9cjp.js"
17
+ "_vendor-BEuNhfwH.js",
18
+ "_vendor-arizeai-Bskhzyjm.js",
19
+ "_components-MllbfxfJ.js",
20
+ "_vendor-recharts-CRqhvLYg.js",
21
+ "_vendor-codemirror-DLlXCf0x.js"
22
22
  ]
23
23
  },
24
24
  "_vendor-!~{003}~.js": {
25
25
  "file": "assets/vendor-DxkFTwjz.css",
26
26
  "src": "_vendor-!~{003}~.js"
27
27
  },
28
- "_vendor-CtqfhlbC.js": {
29
- "file": "assets/vendor-CtqfhlbC.js",
28
+ "_vendor-BEuNhfwH.js": {
29
+ "file": "assets/vendor-BEuNhfwH.js",
30
30
  "name": "vendor",
31
31
  "imports": [
32
32
  "_vendor-three-DwGkEfCM.js"
@@ -35,25 +35,25 @@
35
35
  "assets/vendor-DxkFTwjz.css"
36
36
  ]
37
37
  },
38
- "_vendor-arizeai-C_3SBz56.js": {
39
- "file": "assets/vendor-arizeai-C_3SBz56.js",
38
+ "_vendor-arizeai-Bskhzyjm.js": {
39
+ "file": "assets/vendor-arizeai-Bskhzyjm.js",
40
40
  "name": "vendor-arizeai",
41
41
  "imports": [
42
- "_vendor-CtqfhlbC.js"
42
+ "_vendor-BEuNhfwH.js"
43
43
  ]
44
44
  },
45
- "_vendor-codemirror-wfdk9cjp.js": {
46
- "file": "assets/vendor-codemirror-wfdk9cjp.js",
45
+ "_vendor-codemirror-DLlXCf0x.js": {
46
+ "file": "assets/vendor-codemirror-DLlXCf0x.js",
47
47
  "name": "vendor-codemirror",
48
48
  "imports": [
49
- "_vendor-CtqfhlbC.js"
49
+ "_vendor-BEuNhfwH.js"
50
50
  ]
51
51
  },
52
- "_vendor-recharts-BiVnSv90.js": {
53
- "file": "assets/vendor-recharts-BiVnSv90.js",
52
+ "_vendor-recharts-CRqhvLYg.js": {
53
+ "file": "assets/vendor-recharts-CRqhvLYg.js",
54
54
  "name": "vendor-recharts",
55
55
  "imports": [
56
- "_vendor-CtqfhlbC.js"
56
+ "_vendor-BEuNhfwH.js"
57
57
  ]
58
58
  },
59
59
  "_vendor-three-DwGkEfCM.js": {
@@ -61,18 +61,18 @@
61
61
  "name": "vendor-three"
62
62
  },
63
63
  "index.tsx": {
64
- "file": "assets/index-DLe1Oo3l.js",
64
+ "file": "assets/index-BVO2YcT1.js",
65
65
  "name": "index",
66
66
  "src": "index.tsx",
67
67
  "isEntry": true,
68
68
  "imports": [
69
- "_vendor-CtqfhlbC.js",
70
- "_vendor-arizeai-C_3SBz56.js",
71
- "_pages-C8-Sl7JI.js",
72
- "_components-C70HJiXz.js",
69
+ "_vendor-BEuNhfwH.js",
70
+ "_vendor-arizeai-Bskhzyjm.js",
71
+ "_pages-BHfC6jnL.js",
72
+ "_components-MllbfxfJ.js",
73
73
  "_vendor-three-DwGkEfCM.js",
74
- "_vendor-recharts-BiVnSv90.js",
75
- "_vendor-codemirror-wfdk9cjp.js"
74
+ "_vendor-recharts-CRqhvLYg.js",
75
+ "_vendor-codemirror-DLlXCf0x.js"
76
76
  ]
77
77
  }
78
78
  }