arize-phoenix 7.9.4__py3-none-any.whl → 7.10.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of arize-phoenix might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arize-phoenix
3
- Version: 7.9.4
3
+ Version: 7.10.1
4
4
  Summary: AI Observability and Evaluation
5
5
  Project-URL: Documentation, https://docs.arize.com/phoenix/
6
6
  Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
@@ -6,7 +6,7 @@ phoenix/exceptions.py,sha256=n2L2KKuecrdflB9MsCdAYCiSEvGJptIsfRkXMoJle7A,169
6
6
  phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
7
7
  phoenix/services.py,sha256=kpW1WL0kiB8XJsO6XycvZVJ-lBkNoenhQ7atCvBoSe8,5365
8
8
  phoenix/settings.py,sha256=ht-0oN-sMV6SPXrk7Tu1EZlngpAYkGNLYPhO8DyrdQI,661
9
- phoenix/version.py,sha256=gXpiGD95etHJBoLtm8Ou9WzXU9xwu4-1qgbCn6UVjtI,22
9
+ phoenix/version.py,sha256=XwgZPJjIv2f1bicnWwDXrs8caKKb1ZMWLcgcnaWDqFU,23
10
10
  phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
12
12
  phoenix/core/model.py,sha256=qBFraOtmwCCnWJltKNP18DDG0mULXigytlFsa6YOz6k,4837
@@ -97,7 +97,7 @@ phoenix/server/api/exceptions.py,sha256=TA0JuY2YRnj35qGuMSQ8d0ToHum9gWm9W--3fSKH
97
97
  phoenix/server/api/interceptor.py,sha256=ykDnoC_apUd-llVli3m1CW18kNSIgjz2qZ6m5JmPDu8,1294
98
98
  phoenix/server/api/queries.py,sha256=trLnegFnJemcjWZ9PVNifdrLe6Fq4mmaPFG-rq6zByY,29168
99
99
  phoenix/server/api/schema.py,sha256=fcs36xQwFF_Qe41_5cWR8wYpDvOrnbcyTeo5WNMbDsA,1702
100
- phoenix/server/api/subscriptions.py,sha256=vN5KI4K28N3PN621Fcy_ksnx_C80VxOCWgFqp7j96_E,23602
100
+ phoenix/server/api/subscriptions.py,sha256=B91rCAnNEC6t3mLDlKnrmPCO52kr2ZyDWJ6b2_Vqm48,23069
101
101
  phoenix/server/api/utils.py,sha256=quCBRcusc6PUq9tJq7M8PgwFZp7nXgVAxtbw8feribY,833
102
102
  phoenix/server/api/dataloaders/__init__.py,sha256=nt5Lbs34q05GSvNCT2IGrkRW0kg65L8h3bZelzgpkYg,3909
103
103
  phoenix/server/api/dataloaders/annotation_summaries.py,sha256=2sHmIDX7n8tuPeBTs9bMKtlMKWn_Ph9awTZqmwn2Owc,5505
@@ -133,9 +133,9 @@ phoenix/server/api/dataloaders/users.py,sha256=Uh86Kny_xpqDdEvEklcTBUA_MELgu4Z0j
133
133
  phoenix/server/api/dataloaders/cache/__init__.py,sha256=SYoOM9n8FJaMdQarma5d1blu-jIg2GB8Shqg5ezSzZ8,106
134
134
  phoenix/server/api/dataloaders/cache/two_tier_cache.py,sha256=cmo8FUT3E91R139IEzh4yCga-6nTamc5KPXAfMrzNDM,2315
135
135
  phoenix/server/api/helpers/__init__.py,sha256=m2-xaSPqUiSs91k62JaRDjFNfl-1byxBfY-m_Vxw16U,272
136
- phoenix/server/api/helpers/dataset_helpers.py,sha256=AMlKY9_e0wnTrTSSQemM5NHfnpwARSytx-m9YK6f6bY,8421
136
+ phoenix/server/api/helpers/dataset_helpers.py,sha256=DoMBTg-qXTnC_K4Evx1WKpCCYgRbITpVqyY-8efJRf0,8984
137
137
  phoenix/server/api/helpers/experiment_run_filters.py,sha256=DOnVwrmn39eAkk2mwuZP8kIcAnR5jrOgllEwWSjsw94,29893
138
- phoenix/server/api/helpers/playground_clients.py,sha256=JoMYwhCd8AyRFG58y6PkUZBJnKMFLptIx5jnE2lY7r0,38955
138
+ phoenix/server/api/helpers/playground_clients.py,sha256=HAGZpLp7DUjuuTslo0Yfw2N-TEUKmHJ1XwaRe3mWfyA,38979
139
139
  phoenix/server/api/helpers/playground_registry.py,sha256=CPLMziFB2wmr-dfbx7VbzO2f8YIG_k5RftzvGXYGQ1w,2570
140
140
  phoenix/server/api/helpers/playground_spans.py,sha256=qGk7V7IZK7EkRE1mvZyROpLN5kgOahOZifFzUWmqYFc,16546
141
141
  phoenix/server/api/input_types/AddExamplesToDatasetInput.py,sha256=mIQz0S_z8YdrktKIY6RCvtNJ2yZF9pYvTGgasUsI-54,430
@@ -158,7 +158,7 @@ phoenix/server/api/input_types/DeleteDatasetInput.py,sha256=p7xjCyWnVCIXHnezmDiW
158
158
  phoenix/server/api/input_types/DeleteExperimentsInput.py,sha256=4d9N0vSLYbuysAamGoPUP_m8vdVhwrZmXoi2vhy_HdI,141
159
159
  phoenix/server/api/input_types/DimensionFilter.py,sha256=eBYcn7ECSJQlEePvbStqkHBRicbIL4vEAzFJwX7bacQ,3137
160
160
  phoenix/server/api/input_types/DimensionInput.py,sha256=Vfx5FmiMKey4-EHDQsQRPzSAMRJMN5oVMLDUl4NKAa8,164
161
- phoenix/server/api/input_types/GenerativeModelInput.py,sha256=h_9dNkz-LBgOLKQ5_ijch4UNGiDb4x5CCC96WyverSg,551
161
+ phoenix/server/api/input_types/GenerativeModelInput.py,sha256=8eRKLMVwXbfc6QVQySN43BDA1JEY09a2x0Egy4K0jAQ,815
162
162
  phoenix/server/api/input_types/Granularity.py,sha256=dbBlD_GsIBa8_xrx4JlLuR59bQ0NRB5H-cv1zvcb-cw,2299
163
163
  phoenix/server/api/input_types/InvocationParameters.py,sha256=I_FvPvY2sXxNd-kFSB96-1DOW7lo-VbqVWzppU_5hy8,5196
164
164
  phoenix/server/api/input_types/PatchAnnotationInput.py,sha256=NWhkcbcGNPwfOYsN3wm5YFNNrSc5T-8Y5my74RK99HE,520
@@ -175,8 +175,8 @@ phoenix/server/api/input_types/UserRoleInput.py,sha256=xxhFe0ITZOgRVEJbVem_W6F1I
175
175
  phoenix/server/api/input_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
176
  phoenix/server/api/mutations/__init__.py,sha256=1wClieLNA3_Tin4Ah67rkrQvwSSZAdPU0EPsRiUxyAA,1103
177
177
  phoenix/server/api/mutations/api_key_mutations.py,sha256=diNBL06zrFCmzR-leYbL-AxDqN05-YtbzsnsAdew_K8,6194
178
- phoenix/server/api/mutations/chat_mutations.py,sha256=FM5Dfdrc4N_1juL8yWKk3TVGo3qaLxfajKjxqm0MIgs,23069
179
- phoenix/server/api/mutations/dataset_mutations.py,sha256=Br7eJeeuX_fXPWBFny3upCPJuhllhYMnAm4uHrxNNaQ,26158
178
+ phoenix/server/api/mutations/chat_mutations.py,sha256=EF9aNTBb0tSGfnzCwq2JkLqd_NLQWikHRaUC85FM0Xs,22768
179
+ phoenix/server/api/mutations/dataset_mutations.py,sha256=V52mL0vizxL9cvWWBkmd19rGu8xvu-B8LOosZkROPIk,27004
180
180
  phoenix/server/api/mutations/experiment_mutations.py,sha256=p3CoLAa8nFPa3D759Y2A7De_PVJNGOL98mA3HoZBrRQ,3188
181
181
  phoenix/server/api/mutations/export_events_mutations.py,sha256=xoDnVWC7eA_8wNQP0-oyiHojyUZ0EhVVSrsAnztetC0,3993
182
182
  phoenix/server/api/mutations/project_mutations.py,sha256=u7kLvJbBFR418F9lMamiisZerF18E8h5wGKV4sDTF-g,2674
@@ -192,7 +192,7 @@ phoenix/server/api/routers/embeddings.py,sha256=BpZGJee0pdL0W5Rp1L0b30dEtZTgJeVq
192
192
  phoenix/server/api/routers/oauth2.py,sha256=bSrTZAAWW4WgZVwkr39xbo5jZEYL4w4wCbEe280M6f0,17157
193
193
  phoenix/server/api/routers/utils.py,sha256=M41BoH-fl37izhRuN2aX7lWm7jOC20A_3uClv9TVUUY,583
194
194
  phoenix/server/api/routers/v1/__init__.py,sha256=aLEHzzU8kQo4Oqsv2an35lH5VYUxAZQrcG7CXZA_Lx4,2214
195
- phoenix/server/api/routers/v1/datasets.py,sha256=tNh0CxAvSkWh-_5AwisGN1degQlUNGU3uufGa7MIbOw,36985
195
+ phoenix/server/api/routers/v1/datasets.py,sha256=AkcevhK-mvE9EWLia135XLoqatFFmYBzzOs7ZnNpgCs,37066
196
196
  phoenix/server/api/routers/v1/evaluations.py,sha256=RpOkTylp5Da6BvPZGuN8ksnxz_BVXRIwyOvwX9Iko8U,12647
197
197
  phoenix/server/api/routers/v1/experiment_evaluations.py,sha256=1XuKqE5F6CC6R4kF4g4YdBtcYvch1rCk8Am5CGyqfJ4,4838
198
198
  phoenix/server/api/routers/v1/experiment_runs.py,sha256=xKXhol1-G4zAFECAQK9lAjKtSJsvB0Bp6bAXJYqJ7eI,6387
@@ -287,10 +287,10 @@ phoenix/server/static/apple-touch-icon-76x76.png,sha256=CT_xT12I0u2i0WU8JzBZBuOQ
287
287
  phoenix/server/static/apple-touch-icon.png,sha256=fOfpjqGpWYbJ0eAurKsyoZP1EAs6ZVooBJ_SGk2ZkDs,3801
288
288
  phoenix/server/static/favicon.ico,sha256=bY0vvCKRftemZfPShwZtE93DiiQdaYaozkPGwNFr6H8,34494
289
289
  phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
290
- phoenix/server/static/.vite/manifest.json,sha256=s6u7joWl3foLAUDiN6VPjyv0Yu0RpbEZG5xxNxAoOmo,2163
291
- phoenix/server/static/assets/components-DOevqttF.js,sha256=ngQTLIfMdg1Ylg7hOnsDp5oDX8AAltGMD4Bee0bDmg8,390205
292
- phoenix/server/static/assets/index-DEWan9NY.js,sha256=jkFJECR5YMzEO6fP4okbWTVQCMUvvqvQovnd3rEGGoA,8711
293
- phoenix/server/static/assets/pages-iAiRxguB.js,sha256=-2uBkfXmIhBNtfMd3TBWX1Rh1YPdqGxO-g_QWs1d9sA,680657
290
+ phoenix/server/static/.vite/manifest.json,sha256=NHCeI0pJkXZgIN0NWm8m8NDodWYE5DIX8h8Sb-ZuYPY,2163
291
+ phoenix/server/static/assets/components-Bo_Bsbf_.js,sha256=5sEC-asgY8AxrEK_8y-flzP4eR1Y6wRc1_gGmi5wVUQ,390283
292
+ phoenix/server/static/assets/index-_a0bc8_O.js,sha256=cJduWJXpGENIcpDNfld6vIeBydGeBvQodW-AQDlJn_s,8711
293
+ phoenix/server/static/assets/pages-BEC7GxQJ.js,sha256=DO-87eE-qBmVRwmjrqiyY4KYaEPq-LhbrIvln6PWQNc,681219
294
294
  phoenix/server/static/assets/vendor-DvC8cT4X.js,sha256=-EzJrg6BeYa58JPfaZC6KS5gvkJ8gC1n-Sb7lP-pOkw,2159677
295
295
  phoenix/server/static/assets/vendor-DxkFTwjz.css,sha256=nZrkr0u6NNElFGvpWHk9GTHeGoibCXCli1bE7mXZGZg,1816
296
296
  phoenix/server/static/assets/vendor-arizeai-Do1793cv.js,sha256=IFADVVEZ8VY9o4iqYighRedZTXSyi1uZMTFFsBeIYis,305184
@@ -304,7 +304,7 @@ phoenix/session/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
304
304
  phoenix/session/client.py,sha256=jGc-jQuFUPdJc4AGcPPkVbnw7Qui8Lm7V6fjPntxkzo,35330
305
305
  phoenix/session/data_extractor.py,sha256=Y0RzYFaNy9fQj8PEIeQ76TBZ90_E1FW7bXu3K5x0EZY,2782
306
306
  phoenix/session/evaluation.py,sha256=Q3fOMNELvqkk-b6a6PKc8pDJdsNQ0ZbTpseUSA2NKqs,5300
307
- phoenix/session/session.py,sha256=1HMKmN4Sn6W3szajitR5EQ130ia1HxIhTUB_tew6P00,27474
307
+ phoenix/session/session.py,sha256=nD0v1VWQVOnKpviK2RjjFV3YLcNdrDkrclsK64Y3H6Y,27540
308
308
  phoenix/trace/__init__.py,sha256=ujk_uYjM8gmm-YqnyXxF-kekfwid0bcaPMTtNNcaw6U,407
309
309
  phoenix/trace/attributes.py,sha256=mHpOtdjGIs-VGSev_dwvxTeZTc9GILovi1Rdnj56HO0,12457
310
310
  phoenix/trace/errors.py,sha256=wB1z8qdPckngdfU-TORToekvg3344oNFAA83_hC2yFY,180
@@ -337,9 +337,9 @@ phoenix/utilities/project.py,sha256=auVpARXkDb-JgeX5f2aStyFIkeKvGwN9l7qrFeJMVxI,
337
337
  phoenix/utilities/re.py,sha256=6YyUWIkv0zc2SigsxfOWIHzdpjKA_TZo2iqKq7zJKvw,2081
338
338
  phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
339
339
  phoenix/utilities/template_formatters.py,sha256=gh9PJD6WEGw7TEYXfSst1UR4pWWwmjxMLrDVQ_CkpkQ,2779
340
- arize_phoenix-7.9.4.dist-info/METADATA,sha256=YnZR0pVt7yoNByDcbS5KfXfWgHnlPwzQeuKtrxwOXvw,23389
341
- arize_phoenix-7.9.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
342
- arize_phoenix-7.9.4.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
343
- arize_phoenix-7.9.4.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
344
- arize_phoenix-7.9.4.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
345
- arize_phoenix-7.9.4.dist-info/RECORD,,
340
+ arize_phoenix-7.10.1.dist-info/METADATA,sha256=iuzOzhheVYvQQ75S20DuEzHp_ZmGUPHdAkiQziovsVo,23390
341
+ arize_phoenix-7.10.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
342
+ arize_phoenix-7.10.1.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
343
+ arize_phoenix-7.10.1.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
344
+ arize_phoenix-7.10.1.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
345
+ arize_phoenix-7.10.1.dist-info/RECORD,,
@@ -7,6 +7,7 @@ from openinference.semconv.trace import (
7
7
  OpenInferenceMimeTypeValues,
8
8
  OpenInferenceSpanKindValues,
9
9
  SpanAttributes,
10
+ ToolAttributes,
10
11
  ToolCallAttributes,
11
12
  )
12
13
 
@@ -27,12 +28,18 @@ def get_dataset_example_input(span: Span) -> dict[str, Any]:
27
28
  input_mime_type = get_attribute_value(attributes, INPUT_MIME_TYPE)
28
29
  prompt_template_variables = get_attribute_value(attributes, LLM_PROMPT_TEMPLATE_VARIABLES)
29
30
  input_messages = get_attribute_value(attributes, LLM_INPUT_MESSAGES)
31
+ tool_definitions = []
32
+ if tools := get_attribute_value(attributes, LLM_TOOLS):
33
+ for tool in tools:
34
+ if definition := get_attribute_value(tool, TOOL_DEFINITION):
35
+ tool_definitions.append(definition)
30
36
  if span_kind == LLM:
31
37
  return _get_llm_span_input(
32
38
  input_messages=input_messages,
33
39
  input_value=input_value,
34
40
  input_mime_type=input_mime_type,
35
41
  prompt_template_variables=prompt_template_variables,
42
+ tools=tool_definitions,
36
43
  )
37
44
  return _get_generic_io_value(io_value=input_value, mime_type=input_mime_type, kind="input")
38
45
 
@@ -71,6 +78,7 @@ def _get_llm_span_input(
71
78
  input_value: Any,
72
79
  input_mime_type: Optional[str],
73
80
  prompt_template_variables: Any,
81
+ tools: Any,
74
82
  ) -> dict[str, Any]:
75
83
  """
76
84
  Extracts the input value from an LLM span and returns it as a dictionary.
@@ -84,6 +92,8 @@ def _get_llm_span_input(
84
92
  input = _get_generic_io_value(io_value=input_value, mime_type=input_mime_type, kind="input")
85
93
  if prompt_template_variables_data := _safely_json_decode(prompt_template_variables):
86
94
  input["prompt_template_variables"] = prompt_template_variables_data
95
+ if tool_definitions_data := [_safely_json_decode(tool_definition) for tool_definition in tools]:
96
+ input["tools"] = tool_definitions_data
87
97
  return input
88
98
 
89
99
 
@@ -215,3 +225,7 @@ RETRIEVAL_DOCUMENTS = SpanAttributes.RETRIEVAL_DOCUMENTS
215
225
  # ToolCallAttributes
216
226
  TOOL_CALL_FUNCTION_ARGUMENTS_JSON = ToolCallAttributes.TOOL_CALL_FUNCTION_ARGUMENTS_JSON
217
227
  TOOL_CALL_FUNCTION_NAME = ToolCallAttributes.TOOL_CALL_FUNCTION_NAME
228
+
229
+ # ToolAttributes
230
+ LLM_TOOLS = SpanAttributes.LLM_TOOLS
231
+ TOOL_DEFINITION = ToolAttributes.TOOL_JSON_SCHEMA
@@ -477,11 +477,10 @@ class OpenAIStreamingClient(OpenAIBaseStreamingClient):
477
477
  ) -> None:
478
478
  from openai import AsyncOpenAI
479
479
 
480
- # todo: check if custom base url is set before raising error to allow
481
- # for custom endpoints that don't require an API key
482
- if not (api_key := api_key or os.environ.get("OPENAI_API_KEY")):
480
+ base_url = model.base_url or os.environ.get("OPENAI_BASE_URL")
481
+ if not (api_key := api_key or os.environ.get("OPENAI_API_KEY")) and not base_url:
483
482
  raise BadRequest("An API key is required for OpenAI models")
484
- client = AsyncOpenAI(api_key=api_key)
483
+ client = AsyncOpenAI(api_key=api_key, base_url=base_url)
485
484
  super().__init__(client=client, model=model, api_key=api_key)
486
485
  self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.OPENAI.value
487
486
  self._attributes[LLM_SYSTEM] = OpenInferenceLLMSystemValues.OPENAI.value
@@ -496,9 +495,11 @@ class OpenAIStreamingClient(OpenAIBaseStreamingClient):
496
495
  "o1-mini-2024-09-12",
497
496
  "o1-preview",
498
497
  "o1-preview-2024-09-12",
498
+ "o3-mini",
499
+ "o3-mini-2025-01-31",
499
500
  ],
500
501
  )
501
- class OpenAIO1StreamingClient(OpenAIStreamingClient):
502
+ class OpenAIReasoningStreamingClient(OpenAIStreamingClient):
502
503
  @classmethod
503
504
  def supported_invocation_parameters(cls) -> list[InvocationParameter]:
504
505
  return [
@@ -11,7 +11,13 @@ class GenerativeModelInput:
11
11
  provider_key: GenerativeProviderKey
12
12
  name: str
13
13
  """ The name of the model. Or the Deployment Name for Azure OpenAI models. """
14
+ base_url: Optional[str] = UNSET
15
+ """ The base URL to use for the model. """
14
16
  endpoint: Optional[str] = UNSET
15
17
  """ The endpoint to use for the model. Only required for Azure OpenAI models. """
16
18
  api_version: Optional[str] = UNSET
17
19
  """ The API version to use for the model. """
20
+
21
+ def __post_init__(self) -> None:
22
+ if self.base_url and self.endpoint:
23
+ raise ValueError("Must not provide both a base URL and an endpoint at the same time.")
@@ -49,7 +49,6 @@ from phoenix.server.api.input_types.ChatCompletionInput import (
49
49
  from phoenix.server.api.input_types.TemplateOptions import TemplateOptions
50
50
  from phoenix.server.api.subscriptions import (
51
51
  _default_playground_experiment_description,
52
- _default_playground_experiment_metadata,
53
52
  _default_playground_experiment_name,
54
53
  )
55
54
  from phoenix.server.api.types.ChatCompletionMessageRole import ChatCompletionMessageRole
@@ -183,12 +182,7 @@ class ChatCompletionMutationMixin:
183
182
  description=input.experiment_description
184
183
  or _default_playground_experiment_description(dataset_name=dataset.name),
185
184
  repetitions=1,
186
- metadata_=input.experiment_metadata
187
- or _default_playground_experiment_metadata(
188
- dataset_name=dataset.name,
189
- dataset_id=input.dataset_id,
190
- version_id=GlobalID(DatasetVersion.__name__, str(resolved_version_id)),
191
- ),
185
+ metadata_=input.experiment_metadata or dict(),
192
186
  project_name=PLAYGROUND_PROJECT_NAME,
193
187
  )
194
188
  session.add(experiment)
@@ -4,7 +4,11 @@ from typing import Any
4
4
 
5
5
  import strawberry
6
6
  from openinference.semconv.trace import (
7
+ MessageAttributes,
8
+ MessageContentAttributes,
7
9
  SpanAttributes,
10
+ ToolAttributes,
11
+ ToolCallAttributes,
8
12
  )
9
13
  from sqlalchemy import and_, delete, distinct, func, insert, select, update
10
14
  from strawberry import UNSET
@@ -181,6 +185,17 @@ class DatasetMutationMixin:
181
185
  assert all(map(lambda id: isinstance(id, int), dataset_example_rowids))
182
186
  DatasetExampleRevision = models.DatasetExampleRevision
183
187
 
188
+ all_span_attributes = {
189
+ **SpanAttributes.__dict__,
190
+ **MessageAttributes.__dict__,
191
+ **MessageContentAttributes.__dict__,
192
+ **ToolCallAttributes.__dict__,
193
+ **ToolAttributes.__dict__,
194
+ }
195
+ nonprivate_span_attributes = {
196
+ k: v for k, v in all_span_attributes.items() if not k.startswith("_")
197
+ }
198
+
184
199
  await session.execute(
185
200
  insert(DatasetExampleRevision),
186
201
  [
@@ -190,6 +205,12 @@ class DatasetMutationMixin:
190
205
  DatasetExampleRevision.input.key: get_dataset_example_input(span),
191
206
  DatasetExampleRevision.output.key: get_dataset_example_output(span),
192
207
  DatasetExampleRevision.metadata_.key: {
208
+ **(span.attributes.get(SpanAttributes.METADATA) or dict()),
209
+ **{
210
+ k: v
211
+ for k, v in span.attributes.items()
212
+ if k in nonprivate_span_attributes
213
+ },
193
214
  "span_kind": span.span_kind,
194
215
  **(
195
216
  {"annotations": annotations}
@@ -919,20 +919,23 @@ def _get_content_csv(examples: list[models.DatasetExampleRevision]) -> bytes:
919
919
  def _get_content_jsonl_openai_ft(examples: list[models.DatasetExampleRevision]) -> bytes:
920
920
  records = io.BytesIO()
921
921
  for ex in examples:
922
- records.write(
923
- (
924
- json.dumps(
925
- {
926
- "messages": (
927
- ims if isinstance(ims := ex.input.get("messages"), list) else []
928
- )
929
- + (oms if isinstance(oms := ex.output.get("messages"), list) else [])
930
- },
931
- ensure_ascii=False,
932
- )
933
- + "\n"
934
- ).encode()
935
- )
922
+ input_messages = ex.input.get("messages", [])
923
+ if not isinstance(input_messages, list):
924
+ input_messages = []
925
+ output_messages = ex.output.get("messages", [])
926
+ if not isinstance(output_messages, list):
927
+ output_messages = []
928
+
929
+ record_dict = {
930
+ "messages": input_messages + output_messages,
931
+ }
932
+
933
+ tools = ex.input.get("tools", [])
934
+ if tools:
935
+ record_dict["tools"] = tools
936
+
937
+ records.write((json.dumps(record_dict, ensure_ascii=False) + "\n").encode())
938
+
936
939
  records.seek(0)
937
940
  return records.read()
938
941
 
@@ -278,12 +278,7 @@ class Subscription:
278
278
  description=input.experiment_description
279
279
  or _default_playground_experiment_description(dataset_name=dataset.name),
280
280
  repetitions=1,
281
- metadata_=input.experiment_metadata
282
- or _default_playground_experiment_metadata(
283
- dataset_name=dataset.name,
284
- dataset_id=input.dataset_id,
285
- version_id=GlobalID(DatasetVersion.__name__, str(resolved_version_id)),
286
- ),
281
+ metadata_=input.experiment_metadata or dict(),
287
282
  project_name=PLAYGROUND_PROJECT_NAME,
288
283
  )
289
284
  session.add(experiment)
@@ -581,16 +576,6 @@ def _default_playground_experiment_description(dataset_name: str) -> str:
581
576
  return f'Playground experiment for dataset "{dataset_name}"'
582
577
 
583
578
 
584
- def _default_playground_experiment_metadata(
585
- dataset_name: str, dataset_id: GlobalID, version_id: GlobalID
586
- ) -> dict[str, Any]:
587
- return {
588
- "dataset_name": dataset_name,
589
- "dataset_id": str(dataset_id),
590
- "dataset_version_id": str(version_id),
591
- }
592
-
593
-
594
579
  LLM_OUTPUT_MESSAGES = SpanAttributes.LLM_OUTPUT_MESSAGES
595
580
  LLM_TOKEN_COUNT_COMPLETION = SpanAttributes.LLM_TOKEN_COUNT_COMPLETION
596
581
  LLM_TOKEN_COUNT_PROMPT = SpanAttributes.LLM_TOKEN_COUNT_PROMPT
@@ -1,22 +1,22 @@
1
1
  {
2
- "_components-DOevqttF.js": {
3
- "file": "assets/components-DOevqttF.js",
2
+ "_components-Bo_Bsbf_.js": {
3
+ "file": "assets/components-Bo_Bsbf_.js",
4
4
  "name": "components",
5
5
  "imports": [
6
6
  "_vendor-DvC8cT4X.js",
7
- "_pages-iAiRxguB.js",
7
+ "_pages-BEC7GxQJ.js",
8
8
  "_vendor-arizeai-Do1793cv.js",
9
9
  "_vendor-codemirror-BzwZPyJM.js",
10
10
  "_vendor-three-DwGkEfCM.js"
11
11
  ]
12
12
  },
13
- "_pages-iAiRxguB.js": {
14
- "file": "assets/pages-iAiRxguB.js",
13
+ "_pages-BEC7GxQJ.js": {
14
+ "file": "assets/pages-BEC7GxQJ.js",
15
15
  "name": "pages",
16
16
  "imports": [
17
17
  "_vendor-DvC8cT4X.js",
18
18
  "_vendor-arizeai-Do1793cv.js",
19
- "_components-DOevqttF.js",
19
+ "_components-Bo_Bsbf_.js",
20
20
  "_vendor-codemirror-BzwZPyJM.js",
21
21
  "_vendor-recharts-_Jb7JjhG.js"
22
22
  ]
@@ -69,15 +69,15 @@
69
69
  "name": "vendor-three"
70
70
  },
71
71
  "index.tsx": {
72
- "file": "assets/index-DEWan9NY.js",
72
+ "file": "assets/index-_a0bc8_O.js",
73
73
  "name": "index",
74
74
  "src": "index.tsx",
75
75
  "isEntry": true,
76
76
  "imports": [
77
77
  "_vendor-DvC8cT4X.js",
78
78
  "_vendor-arizeai-Do1793cv.js",
79
- "_pages-iAiRxguB.js",
80
- "_components-DOevqttF.js",
79
+ "_pages-BEC7GxQJ.js",
80
+ "_components-Bo_Bsbf_.js",
81
81
  "_vendor-three-DwGkEfCM.js",
82
82
  "_vendor-codemirror-BzwZPyJM.js",
83
83
  "_vendor-shiki-Cl9QBraO.js",