arize-phoenix 11.7.0__py3-none-any.whl → 11.9.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 (42) hide show
  1. {arize_phoenix-11.7.0.dist-info → arize_phoenix-11.9.0.dist-info}/METADATA +14 -2
  2. {arize_phoenix-11.7.0.dist-info → arize_phoenix-11.9.0.dist-info}/RECORD +39 -37
  3. phoenix/config.py +33 -0
  4. phoenix/datetime_utils.py +112 -1
  5. phoenix/db/helpers.py +156 -1
  6. phoenix/db/insertion/span.py +12 -10
  7. phoenix/db/insertion/types.py +9 -2
  8. phoenix/server/api/auth.py +28 -6
  9. phoenix/server/api/dataloaders/span_cost_summary_by_experiment.py +6 -7
  10. phoenix/server/api/exceptions.py +6 -0
  11. phoenix/server/api/input_types/CreateProjectInput.py +27 -0
  12. phoenix/server/api/input_types/TimeBinConfig.py +23 -0
  13. phoenix/server/api/mutations/project_mutations.py +37 -1
  14. phoenix/server/api/mutations/trace_mutations.py +45 -1
  15. phoenix/server/api/routers/oauth2.py +19 -2
  16. phoenix/server/api/types/CostBreakdown.py +4 -7
  17. phoenix/server/api/types/Project.py +891 -69
  18. phoenix/server/app.py +7 -3
  19. phoenix/server/authorization.py +27 -2
  20. phoenix/server/cost_tracking/cost_details_calculator.py +22 -16
  21. phoenix/server/cost_tracking/model_cost_manifest.json +85 -0
  22. phoenix/server/daemons/span_cost_calculator.py +2 -8
  23. phoenix/server/dml_event.py +4 -0
  24. phoenix/server/email/sender.py +2 -1
  25. phoenix/server/email/templates/db_disk_usage_notification.html +3 -0
  26. phoenix/server/static/.vite/manifest.json +36 -36
  27. phoenix/server/static/assets/{components-J3qjrjBf.js → components-IBd-PDxA.js} +452 -293
  28. phoenix/server/static/assets/{index-CEObsQf_.js → index-B8EBC_Z5.js} +17 -11
  29. phoenix/server/static/assets/{pages-CW1UdBht.js → pages-6D1duYIe.js} +569 -439
  30. phoenix/server/static/assets/vendor-BzZ0oklU.js +939 -0
  31. phoenix/server/static/assets/vendor-arizeai-CvjUqTrl.js +168 -0
  32. phoenix/server/static/assets/{vendor-codemirror-k3zCIjlN.js → vendor-codemirror-CKK25Gd7.js} +1 -1
  33. phoenix/server/static/assets/vendor-recharts-CWtaRhQC.js +37 -0
  34. phoenix/server/static/assets/{vendor-shiki-DPtuv2M4.js → vendor-shiki-D30GF-p9.js} +1 -1
  35. phoenix/version.py +1 -1
  36. phoenix/server/static/assets/vendor-BnPh9i9e.js +0 -911
  37. phoenix/server/static/assets/vendor-arizeai-Cr9o_Iu_.js +0 -642
  38. phoenix/server/static/assets/vendor-recharts-BdblEuGB.js +0 -59
  39. {arize_phoenix-11.7.0.dist-info → arize_phoenix-11.9.0.dist-info}/WHEEL +0 -0
  40. {arize_phoenix-11.7.0.dist-info → arize_phoenix-11.9.0.dist-info}/entry_points.txt +0 -0
  41. {arize_phoenix-11.7.0.dist-info → arize_phoenix-11.9.0.dist-info}/licenses/IP_NOTICE +0 -0
  42. {arize_phoenix-11.7.0.dist-info → arize_phoenix-11.9.0.dist-info}/licenses/LICENSE +0 -0
phoenix/server/app.py CHANGED
@@ -62,6 +62,7 @@ from phoenix.config import (
62
62
  get_env_host,
63
63
  get_env_host_root_path,
64
64
  get_env_port,
65
+ get_env_support_email,
65
66
  server_instrumentation_is_enabled,
66
67
  verify_server_environment_variables,
67
68
  )
@@ -850,10 +851,13 @@ class DbDiskUsageInterceptor(AsyncServerInterceptor):
850
851
  method_name.endswith("trace.v1.TraceService/Export")
851
852
  and self._db.should_not_insert_or_update
852
853
  ):
853
- await context.abort(
854
- grpc.StatusCode.RESOURCE_EXHAUSTED,
855
- "Database disk usage threshold exceeded",
854
+ details = (
855
+ "Database operations are disabled due to insufficient storage. "
856
+ "Please delete old data or increase storage."
856
857
  )
858
+ if support_email := get_env_support_email():
859
+ details += f" Need help? Contact us at {support_email}"
860
+ await context.abort(grpc.StatusCode.RESOURCE_EXHAUSTED, details)
857
861
  return await method(request_or_iterator, context)
858
862
 
859
863
 
@@ -25,6 +25,7 @@ Usage:
25
25
  from fastapi import HTTPException, Request
26
26
  from fastapi import status as fastapi_status
27
27
 
28
+ from phoenix.config import get_env_support_email
28
29
  from phoenix.server.bearer_auth import PhoenixUser
29
30
 
30
31
 
@@ -54,9 +55,33 @@ def require_admin(request: Request) -> None:
54
55
 
55
56
 
56
57
  def is_not_locked(request: Request) -> None:
58
+ """
59
+ FastAPI dependency to ensure database operations are not locked due to insufficient storage.
60
+
61
+ This dependency checks if data insertion and update operations are disabled due to
62
+ storage capacity limits. When storage thresholds are exceeded, it raises an HTTP 507
63
+ error with actionable guidance for users.
64
+
65
+ Usage:
66
+ Add as a dependency to any route that modifies data:
67
+
68
+ @router.post("/create-data", dependencies=[Depends(is_not_locked)])
69
+ async def create_data(...):
70
+ ...
71
+
72
+ Raises:
73
+ HTTPException: HTTP 507 Insufficient Storage when database operations are locked.
74
+ The error includes guidance on resolving storage issues and support contact
75
+ information if configured.
76
+ """
57
77
  if request.app.state.db.should_not_insert_or_update:
78
+ detail = (
79
+ "Database operations are disabled due to insufficient storage. "
80
+ "Please delete old data or increase storage."
81
+ )
82
+ if support_email := get_env_support_email():
83
+ detail += f" Need help? Contact us at {support_email}"
58
84
  raise HTTPException(
59
85
  status_code=fastapi_status.HTTP_507_INSUFFICIENT_STORAGE,
60
- detail="Operations that insert or update database "
61
- "records are currently not allowed.",
86
+ detail=detail,
62
87
  )
@@ -1,5 +1,5 @@
1
1
  from itertools import chain
2
- from typing import Any, Iterable, Mapping
2
+ from typing import Any, Iterable, Mapping, Optional
3
3
 
4
4
  from typing_extensions import TypeAlias
5
5
 
@@ -60,7 +60,7 @@ class SpanCostDetailsCalculator:
60
60
  for p in prices
61
61
  if p.is_prompt
62
62
  }
63
- if "input" not in self._prompt:
63
+ if self._prompt and "input" not in self._prompt:
64
64
  raise ValueError("Token prices for prompt must include an 'input' token type")
65
65
 
66
66
  # Create calculators for completion token types (is_prompt=False)
@@ -69,7 +69,7 @@ class SpanCostDetailsCalculator:
69
69
  for p in prices
70
70
  if not p.is_prompt
71
71
  }
72
- if "output" not in self._completion:
72
+ if self._completion and "output" not in self._completion:
73
73
  raise ValueError("Token prices for completion must include an 'output' token type")
74
74
 
75
75
  def calculate_details(
@@ -112,6 +112,9 @@ class SpanCostDetailsCalculator:
112
112
  """
113
113
  prompt_details: dict[_TokenType, models.SpanCostDetail] = {}
114
114
  completion_details: dict[_TokenType, models.SpanCostDetail] = {}
115
+ calculator: Optional[TokenCostCalculator]
116
+ cost: Optional[float]
117
+ cost_per_token: Optional[float]
115
118
 
116
119
  # Phase 1: Process detailed token counts from span attributes
117
120
  for is_prompt, prefix, calculators, results in (
@@ -128,18 +131,19 @@ class SpanCostDetailsCalculator:
128
131
  tokens = max(0, int(token_count))
129
132
 
130
133
  # Calculate cost using specific calculator or fallback to default
134
+ calculator = None
135
+ calculator_key = "input" if is_prompt else "output"
131
136
  if token_type in calculators:
132
137
  # Use specific calculator for this token type
133
138
  calculator = calculators[token_type]
134
- else:
135
- # Fallback to default calculator: "input" for prompts,
136
- # "output" for completions
137
- key = "input" if is_prompt else "output"
138
- calculator = calculators[key]
139
- cost = calculator.calculate_cost(attributes, tokens)
139
+ elif calculator_key in calculators:
140
+ calculator = calculators[calculator_key]
140
141
 
141
- # Calculate cost per token (avoid division by zero)
142
- cost_per_token = cost / tokens if tokens else None
142
+ cost = None
143
+ cost_per_token = None
144
+ if calculator:
145
+ cost = calculator.calculate_cost(attributes, tokens)
146
+ cost_per_token = cost / tokens if tokens else None
143
147
 
144
148
  detail = models.SpanCostDetail(
145
149
  token_type=token_type,
@@ -171,11 +175,13 @@ class SpanCostDetailsCalculator:
171
175
  if tokens <= 0:
172
176
  continue
173
177
 
174
- # Calculate cost using guaranteed default calculator (input/output are required)
175
- cost = calculators[token_type].calculate_cost(attributes, tokens)
176
-
177
- # Calculate cost per token (avoid division by zero)
178
- cost_per_token = cost / tokens if cost and tokens else None
178
+ # Calculate cost using calculator if available
179
+ cost = None
180
+ cost_per_token = None
181
+ if token_type in calculators:
182
+ calculator = calculators[token_type]
183
+ cost = calculator.calculate_cost(attributes, tokens)
184
+ cost_per_token = cost / tokens if tokens else None
179
185
 
180
186
  detail = models.SpanCostDetail(
181
187
  token_type=token_type,
@@ -427,6 +427,11 @@
427
427
  "is_prompt": false,
428
428
  "token_type": "output"
429
429
  },
430
+ {
431
+ "base_rate": 2.5e-8,
432
+ "is_prompt": true,
433
+ "token_type": "cache_read"
434
+ },
430
435
  {
431
436
  "base_rate": 7e-7,
432
437
  "is_prompt": true,
@@ -449,6 +454,11 @@
449
454
  "is_prompt": false,
450
455
  "token_type": "output"
451
456
  },
457
+ {
458
+ "base_rate": 3.75e-8,
459
+ "is_prompt": true,
460
+ "token_type": "cache_read"
461
+ },
452
462
  {
453
463
  "base_rate": 1e-6,
454
464
  "is_prompt": true,
@@ -470,6 +480,11 @@
470
480
  "base_rate": 6e-7,
471
481
  "is_prompt": false,
472
482
  "token_type": "output"
483
+ },
484
+ {
485
+ "base_rate": 3.75e-8,
486
+ "is_prompt": true,
487
+ "token_type": "cache_read"
473
488
  }
474
489
  ]
475
490
  },
@@ -488,6 +503,11 @@
488
503
  "is_prompt": false,
489
504
  "token_type": "output"
490
505
  },
506
+ {
507
+ "base_rate": 1.875e-8,
508
+ "is_prompt": true,
509
+ "token_type": "cache_read"
510
+ },
491
511
  {
492
512
  "base_rate": 7.5e-8,
493
513
  "is_prompt": true,
@@ -510,6 +530,11 @@
510
530
  "is_prompt": false,
511
531
  "token_type": "output"
512
532
  },
533
+ {
534
+ "base_rate": 1.875e-8,
535
+ "is_prompt": true,
536
+ "token_type": "cache_read"
537
+ },
513
538
  {
514
539
  "base_rate": 7.5e-8,
515
540
  "is_prompt": true,
@@ -532,6 +557,11 @@
532
557
  "is_prompt": false,
533
558
  "token_type": "output"
534
559
  },
560
+ {
561
+ "base_rate": 2.5e-8,
562
+ "is_prompt": true,
563
+ "token_type": "cache_read"
564
+ },
535
565
  {
536
566
  "base_rate": 7e-7,
537
567
  "is_prompt": true,
@@ -553,6 +583,11 @@
553
583
  "base_rate": 0.00001,
554
584
  "is_prompt": false,
555
585
  "token_type": "output"
586
+ },
587
+ {
588
+ "base_rate": 3.125e-7,
589
+ "is_prompt": true,
590
+ "token_type": "cache_read"
556
591
  }
557
592
  ]
558
593
  },
@@ -571,6 +606,11 @@
571
606
  "is_prompt": false,
572
607
  "token_type": "output"
573
608
  },
609
+ {
610
+ "base_rate": 7.5e-8,
611
+ "is_prompt": true,
612
+ "token_type": "cache_read"
613
+ },
574
614
  {
575
615
  "base_rate": 1e-6,
576
616
  "is_prompt": true,
@@ -593,6 +633,11 @@
593
633
  "is_prompt": false,
594
634
  "token_type": "output"
595
635
  },
636
+ {
637
+ "base_rate": 2.5e-8,
638
+ "is_prompt": true,
639
+ "token_type": "cache_read"
640
+ },
596
641
  {
597
642
  "base_rate": 5e-7,
598
643
  "is_prompt": true,
@@ -615,6 +660,11 @@
615
660
  "is_prompt": false,
616
661
  "token_type": "output"
617
662
  },
663
+ {
664
+ "base_rate": 3.75e-8,
665
+ "is_prompt": true,
666
+ "token_type": "cache_read"
667
+ },
618
668
  {
619
669
  "base_rate": 1e-6,
620
670
  "is_prompt": true,
@@ -637,6 +687,11 @@
637
687
  "is_prompt": false,
638
688
  "token_type": "output"
639
689
  },
690
+ {
691
+ "base_rate": 7.5e-8,
692
+ "is_prompt": true,
693
+ "token_type": "cache_read"
694
+ },
640
695
  {
641
696
  "base_rate": 1e-6,
642
697
  "is_prompt": true,
@@ -658,6 +713,11 @@
658
713
  "base_rate": 0.00001,
659
714
  "is_prompt": false,
660
715
  "token_type": "output"
716
+ },
717
+ {
718
+ "base_rate": 3.125e-7,
719
+ "is_prompt": true,
720
+ "token_type": "cache_read"
661
721
  }
662
722
  ]
663
723
  },
@@ -675,6 +735,11 @@
675
735
  "base_rate": 0.00001,
676
736
  "is_prompt": false,
677
737
  "token_type": "output"
738
+ },
739
+ {
740
+ "base_rate": 3.125e-7,
741
+ "is_prompt": true,
742
+ "token_type": "cache_read"
678
743
  }
679
744
  ]
680
745
  },
@@ -693,6 +758,11 @@
693
758
  "is_prompt": false,
694
759
  "token_type": "output"
695
760
  },
761
+ {
762
+ "base_rate": 3.125e-7,
763
+ "is_prompt": true,
764
+ "token_type": "cache_read"
765
+ },
696
766
  {
697
767
  "base_rate": 1.25e-6,
698
768
  "is_prompt": true,
@@ -715,6 +785,11 @@
715
785
  "is_prompt": false,
716
786
  "token_type": "output"
717
787
  },
788
+ {
789
+ "base_rate": 3.125e-7,
790
+ "is_prompt": true,
791
+ "token_type": "cache_read"
792
+ },
718
793
  {
719
794
  "base_rate": 1.25e-6,
720
795
  "is_prompt": true,
@@ -737,6 +812,11 @@
737
812
  "is_prompt": false,
738
813
  "token_type": "output"
739
814
  },
815
+ {
816
+ "base_rate": 3.125e-7,
817
+ "is_prompt": true,
818
+ "token_type": "cache_read"
819
+ },
740
820
  {
741
821
  "base_rate": 1.25e-6,
742
822
  "is_prompt": true,
@@ -759,6 +839,11 @@
759
839
  "is_prompt": false,
760
840
  "token_type": "output"
761
841
  },
842
+ {
843
+ "base_rate": 3.125e-7,
844
+ "is_prompt": true,
845
+ "token_type": "cache_read"
846
+ },
762
847
  {
763
848
  "base_rate": 7e-7,
764
849
  "is_prompt": true,
@@ -5,7 +5,6 @@ from asyncio import sleep
5
5
  from datetime import datetime
6
6
  from typing import Any, Mapping, NamedTuple, Optional
7
7
 
8
- from sqlalchemy import inspect
9
8
  from typing_extensions import TypeAlias
10
9
 
11
10
  from phoenix.db import models
@@ -84,18 +83,13 @@ class SpanCostCalculator(DaemonTask):
84
83
  start_time=start_time,
85
84
  attributes=attributes,
86
85
  )
87
- if not cost_model:
88
- return None
89
- if not isinstance(inspect(cost_model).attrs.token_prices.loaded_value, list):
90
- return None
91
-
92
- calculator = SpanCostDetailsCalculator(cost_model.token_prices)
86
+ calculator = SpanCostDetailsCalculator(cost_model.token_prices if cost_model else [])
93
87
  details = calculator.calculate_details(attributes)
94
88
  if not details:
95
89
  return None
96
90
 
97
91
  cost = models.SpanCost(
98
- model_id=cost_model.id,
92
+ model_id=cost_model.id if cost_model else None,
99
93
  span_start_time=start_time,
100
94
  )
101
95
  for detail in details:
@@ -33,6 +33,10 @@ class ProjectDmlEvent(DmlEvent):
33
33
  class ProjectDeleteEvent(ProjectDmlEvent): ...
34
34
 
35
35
 
36
+ @dataclass(frozen=True)
37
+ class ProjectInsertEvent(ProjectDmlEvent): ...
38
+
39
+
36
40
  @dataclass(frozen=True)
37
41
  class SpanDmlEvent(ProjectDmlEvent): ...
38
42
 
@@ -8,7 +8,7 @@ from anyio import to_thread
8
8
  from jinja2 import Environment, FileSystemLoader, select_autoescape
9
9
  from typing_extensions import TypeAlias
10
10
 
11
- from phoenix.config import get_env_root_url
11
+ from phoenix.config import get_env_root_url, get_env_support_email
12
12
 
13
13
  EMAIL_TEMPLATE_FOLDER = Path(__file__).parent / "templates"
14
14
 
@@ -96,6 +96,7 @@ class SimpleEmailSender:
96
96
  current_usage_gibibytes=current_usage_gibibytes,
97
97
  allocated_storage_gibibytes=allocated_storage_gibibytes,
98
98
  notification_threshold_percentage=notification_threshold_percentage,
99
+ support_email=get_env_support_email(),
99
100
  )
100
101
 
101
102
  msg = EmailMessage()
@@ -12,5 +12,8 @@
12
12
  <p><strong>Usage Percentage:</strong> {{ ((current_usage_gibibytes / allocated_storage_gibibytes) * 100)|round(1) }}%</p>
13
13
  <p><strong>Notification Threshold:</strong> {{ notification_threshold_percentage }}%</p>
14
14
  <p>Please consider removing old data or increasing your storage allocation to prevent interruption.</p>
15
+ {% if support_email %}
16
+ <p>If you need assistance, please contact support at <a id="support-email" href="mailto:{{ support_email }}">{{ support_email }}</a>.</p>
17
+ {% endif %}
15
18
  </body>
16
19
  </html>
@@ -1,28 +1,28 @@
1
1
  {
2
- "_components-J3qjrjBf.js": {
3
- "file": "assets/components-J3qjrjBf.js",
2
+ "_components-IBd-PDxA.js": {
3
+ "file": "assets/components-IBd-PDxA.js",
4
4
  "name": "components",
5
5
  "imports": [
6
- "_vendor-BnPh9i9e.js",
7
- "_pages-CW1UdBht.js",
8
- "_vendor-arizeai-Cr9o_Iu_.js",
9
- "_vendor-codemirror-k3zCIjlN.js",
6
+ "_vendor-BzZ0oklU.js",
7
+ "_pages-6D1duYIe.js",
8
+ "_vendor-arizeai-CvjUqTrl.js",
9
+ "_vendor-codemirror-CKK25Gd7.js",
10
10
  "_vendor-three-C5WAXd5r.js"
11
11
  ]
12
12
  },
13
- "_pages-CW1UdBht.js": {
14
- "file": "assets/pages-CW1UdBht.js",
13
+ "_pages-6D1duYIe.js": {
14
+ "file": "assets/pages-6D1duYIe.js",
15
15
  "name": "pages",
16
16
  "imports": [
17
- "_vendor-BnPh9i9e.js",
18
- "_vendor-arizeai-Cr9o_Iu_.js",
19
- "_components-J3qjrjBf.js",
20
- "_vendor-codemirror-k3zCIjlN.js",
21
- "_vendor-recharts-BdblEuGB.js"
17
+ "_vendor-BzZ0oklU.js",
18
+ "_vendor-arizeai-CvjUqTrl.js",
19
+ "_components-IBd-PDxA.js",
20
+ "_vendor-codemirror-CKK25Gd7.js",
21
+ "_vendor-recharts-CWtaRhQC.js"
22
22
  ]
23
23
  },
24
- "_vendor-BnPh9i9e.js": {
25
- "file": "assets/vendor-BnPh9i9e.js",
24
+ "_vendor-BzZ0oklU.js": {
25
+ "file": "assets/vendor-BzZ0oklU.js",
26
26
  "name": "vendor",
27
27
  "imports": [
28
28
  "_vendor-three-C5WAXd5r.js"
@@ -35,33 +35,33 @@
35
35
  "file": "assets/vendor-WIZid84E.css",
36
36
  "src": "_vendor-WIZid84E.css"
37
37
  },
38
- "_vendor-arizeai-Cr9o_Iu_.js": {
39
- "file": "assets/vendor-arizeai-Cr9o_Iu_.js",
38
+ "_vendor-arizeai-CvjUqTrl.js": {
39
+ "file": "assets/vendor-arizeai-CvjUqTrl.js",
40
40
  "name": "vendor-arizeai",
41
41
  "imports": [
42
- "_vendor-BnPh9i9e.js"
42
+ "_vendor-BzZ0oklU.js"
43
43
  ]
44
44
  },
45
- "_vendor-codemirror-k3zCIjlN.js": {
46
- "file": "assets/vendor-codemirror-k3zCIjlN.js",
45
+ "_vendor-codemirror-CKK25Gd7.js": {
46
+ "file": "assets/vendor-codemirror-CKK25Gd7.js",
47
47
  "name": "vendor-codemirror",
48
48
  "imports": [
49
- "_vendor-BnPh9i9e.js",
50
- "_vendor-shiki-DPtuv2M4.js"
49
+ "_vendor-BzZ0oklU.js",
50
+ "_vendor-shiki-D30GF-p9.js"
51
51
  ]
52
52
  },
53
- "_vendor-recharts-BdblEuGB.js": {
54
- "file": "assets/vendor-recharts-BdblEuGB.js",
53
+ "_vendor-recharts-CWtaRhQC.js": {
54
+ "file": "assets/vendor-recharts-CWtaRhQC.js",
55
55
  "name": "vendor-recharts",
56
56
  "imports": [
57
- "_vendor-BnPh9i9e.js"
57
+ "_vendor-BzZ0oklU.js"
58
58
  ]
59
59
  },
60
- "_vendor-shiki-DPtuv2M4.js": {
61
- "file": "assets/vendor-shiki-DPtuv2M4.js",
60
+ "_vendor-shiki-D30GF-p9.js": {
61
+ "file": "assets/vendor-shiki-D30GF-p9.js",
62
62
  "name": "vendor-shiki",
63
63
  "imports": [
64
- "_vendor-BnPh9i9e.js"
64
+ "_vendor-BzZ0oklU.js"
65
65
  ]
66
66
  },
67
67
  "_vendor-three-C5WAXd5r.js": {
@@ -69,19 +69,19 @@
69
69
  "name": "vendor-three"
70
70
  },
71
71
  "index.tsx": {
72
- "file": "assets/index-CEObsQf_.js",
72
+ "file": "assets/index-B8EBC_Z5.js",
73
73
  "name": "index",
74
74
  "src": "index.tsx",
75
75
  "isEntry": true,
76
76
  "imports": [
77
- "_vendor-BnPh9i9e.js",
78
- "_vendor-arizeai-Cr9o_Iu_.js",
79
- "_pages-CW1UdBht.js",
80
- "_components-J3qjrjBf.js",
77
+ "_vendor-BzZ0oklU.js",
78
+ "_vendor-arizeai-CvjUqTrl.js",
79
+ "_pages-6D1duYIe.js",
80
+ "_components-IBd-PDxA.js",
81
81
  "_vendor-three-C5WAXd5r.js",
82
- "_vendor-codemirror-k3zCIjlN.js",
83
- "_vendor-shiki-DPtuv2M4.js",
84
- "_vendor-recharts-BdblEuGB.js"
82
+ "_vendor-codemirror-CKK25Gd7.js",
83
+ "_vendor-shiki-D30GF-p9.js",
84
+ "_vendor-recharts-CWtaRhQC.js"
85
85
  ]
86
86
  }
87
87
  }