arize-phoenix 0.0.32rc1__py3-none-any.whl → 0.0.33__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 (71) hide show
  1. {arize_phoenix-0.0.32rc1.dist-info → arize_phoenix-0.0.33.dist-info}/METADATA +11 -5
  2. {arize_phoenix-0.0.32rc1.dist-info → arize_phoenix-0.0.33.dist-info}/RECORD +69 -40
  3. phoenix/__init__.py +3 -1
  4. phoenix/config.py +23 -1
  5. phoenix/core/model_schema.py +14 -37
  6. phoenix/core/model_schema_adapter.py +0 -1
  7. phoenix/core/traces.py +285 -0
  8. phoenix/datasets/dataset.py +14 -21
  9. phoenix/datasets/errors.py +4 -1
  10. phoenix/datasets/schema.py +1 -1
  11. phoenix/datetime_utils.py +87 -0
  12. phoenix/experimental/callbacks/__init__.py +0 -0
  13. phoenix/experimental/callbacks/langchain_tracer.py +228 -0
  14. phoenix/experimental/callbacks/llama_index_trace_callback_handler.py +364 -0
  15. phoenix/experimental/evals/__init__.py +33 -0
  16. phoenix/experimental/evals/functions/__init__.py +4 -0
  17. phoenix/experimental/evals/functions/binary.py +156 -0
  18. phoenix/experimental/evals/functions/common.py +31 -0
  19. phoenix/experimental/evals/functions/generate.py +50 -0
  20. phoenix/experimental/evals/models/__init__.py +4 -0
  21. phoenix/experimental/evals/models/base.py +130 -0
  22. phoenix/experimental/evals/models/openai.py +128 -0
  23. phoenix/experimental/evals/retrievals.py +2 -2
  24. phoenix/experimental/evals/templates/__init__.py +24 -0
  25. phoenix/experimental/evals/templates/default_templates.py +126 -0
  26. phoenix/experimental/evals/templates/template.py +107 -0
  27. phoenix/experimental/evals/utils/__init__.py +0 -0
  28. phoenix/experimental/evals/utils/downloads.py +33 -0
  29. phoenix/experimental/evals/utils/threads.py +27 -0
  30. phoenix/experimental/evals/utils/types.py +9 -0
  31. phoenix/experimental/evals/utils.py +33 -0
  32. phoenix/metrics/binning.py +0 -1
  33. phoenix/metrics/timeseries.py +2 -3
  34. phoenix/server/api/context.py +2 -0
  35. phoenix/server/api/input_types/SpanSort.py +60 -0
  36. phoenix/server/api/schema.py +85 -4
  37. phoenix/server/api/types/DataQualityMetric.py +10 -1
  38. phoenix/server/api/types/Dataset.py +2 -4
  39. phoenix/server/api/types/DatasetInfo.py +10 -0
  40. phoenix/server/api/types/ExportEventsMutation.py +4 -1
  41. phoenix/server/api/types/Functionality.py +15 -0
  42. phoenix/server/api/types/MimeType.py +16 -0
  43. phoenix/server/api/types/Model.py +3 -5
  44. phoenix/server/api/types/SortDir.py +13 -0
  45. phoenix/server/api/types/Span.py +229 -0
  46. phoenix/server/api/types/TimeSeries.py +9 -2
  47. phoenix/server/api/types/pagination.py +2 -0
  48. phoenix/server/app.py +24 -4
  49. phoenix/server/main.py +60 -24
  50. phoenix/server/span_handler.py +39 -0
  51. phoenix/server/static/index.js +956 -479
  52. phoenix/server/thread_server.py +10 -2
  53. phoenix/services.py +39 -16
  54. phoenix/session/session.py +99 -27
  55. phoenix/trace/exporter.py +71 -0
  56. phoenix/trace/filter.py +181 -0
  57. phoenix/trace/fixtures.py +23 -8
  58. phoenix/trace/schemas.py +59 -6
  59. phoenix/trace/semantic_conventions.py +141 -1
  60. phoenix/trace/span_json_decoder.py +60 -6
  61. phoenix/trace/span_json_encoder.py +1 -9
  62. phoenix/trace/trace_dataset.py +100 -8
  63. phoenix/trace/tracer.py +26 -3
  64. phoenix/trace/v1/__init__.py +522 -0
  65. phoenix/trace/v1/trace_pb2.py +52 -0
  66. phoenix/trace/v1/trace_pb2.pyi +351 -0
  67. phoenix/core/dimension_data_type.py +0 -6
  68. phoenix/core/dimension_type.py +0 -9
  69. {arize_phoenix-0.0.32rc1.dist-info → arize_phoenix-0.0.33.dist-info}/WHEEL +0 -0
  70. {arize_phoenix-0.0.32rc1.dist-info → arize_phoenix-0.0.33.dist-info}/licenses/IP_NOTICE +0 -0
  71. {arize_phoenix-0.0.32rc1.dist-info → arize_phoenix-0.0.33.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,522 @@
1
+ import json
2
+ from datetime import datetime, timezone
3
+ from itertools import chain
4
+ from typing import (
5
+ Any,
6
+ Dict,
7
+ Iterable,
8
+ Iterator,
9
+ Mapping,
10
+ Optional,
11
+ SupportsFloat,
12
+ Tuple,
13
+ Union,
14
+ cast,
15
+ )
16
+ from uuid import UUID
17
+
18
+ from google.protobuf.json_format import MessageToDict
19
+ from google.protobuf.struct_pb2 import Struct
20
+ from google.protobuf.timestamp_pb2 import Timestamp
21
+ from google.protobuf.wrappers_pb2 import BoolValue, BytesValue, FloatValue, StringValue
22
+
23
+ import phoenix.trace.v1.trace_pb2 as pb
24
+ from phoenix.trace.schemas import (
25
+ Span,
26
+ SpanContext,
27
+ SpanEvent,
28
+ SpanException,
29
+ SpanKind,
30
+ SpanStatusCode,
31
+ )
32
+ from phoenix.trace.semantic_conventions import (
33
+ DOCUMENT_CONTENT,
34
+ DOCUMENT_ID,
35
+ DOCUMENT_METADATA,
36
+ DOCUMENT_SCORE,
37
+ EMBEDDING_EMBEDDINGS,
38
+ EMBEDDING_MODEL_NAME,
39
+ EMBEDDING_TEXT,
40
+ EMBEDDING_VECTOR,
41
+ EXCEPTION_ESCAPED,
42
+ EXCEPTION_MESSAGE,
43
+ EXCEPTION_STACKTRACE,
44
+ EXCEPTION_TYPE,
45
+ INPUT_MIME_TYPE,
46
+ INPUT_VALUE,
47
+ OUTPUT_MIME_TYPE,
48
+ OUTPUT_VALUE,
49
+ RETRIEVAL_DOCUMENTS,
50
+ MimeType,
51
+ )
52
+
53
+
54
+ def encode(span: Span) -> pb.Span:
55
+ _attributes: Mapping[str, Any] = dict(span.attributes)
56
+ retrieval, _attributes = _excise_retrieval(_attributes)
57
+ embedding, _attributes = _excise_embedding(_attributes)
58
+ input, _attributes = _excise_input(_attributes)
59
+ output, _attributes = _excise_output(_attributes)
60
+ status = pb.Span.Status(message=_maybe_str(span.status_message))
61
+ if span.status_code is SpanStatusCode.ERROR:
62
+ status.code = pb.Span.Status.Code.ERROR
63
+ elif span.status_code is SpanStatusCode.OK:
64
+ status.code = pb.Span.Status.Code.OK
65
+ parent_span_id = BytesValue(value=span.parent_id.bytes) if span.parent_id else None
66
+ pb_span = pb.Span(
67
+ start_time=_as_timestamp(span.start_time),
68
+ end_time=_maybe_timestamp(span.end_time),
69
+ status=status,
70
+ name=span.name,
71
+ kind=span.span_kind.value,
72
+ context=pb.Span.Context(
73
+ trace_id=span.context.trace_id.bytes,
74
+ span_id=span.context.span_id.bytes,
75
+ ),
76
+ parent_span_id=parent_span_id,
77
+ attributes=_maybe_struct(_attributes),
78
+ input=input,
79
+ output=output,
80
+ retrieval=retrieval,
81
+ embedding=embedding,
82
+ )
83
+ for event in span.events:
84
+ if event.name == "exception":
85
+ pb_span.exceptions.append(
86
+ _encode_exception(
87
+ cast(SpanException, event),
88
+ ),
89
+ )
90
+ else:
91
+ pb_span.events.append(
92
+ _encode_event(event),
93
+ )
94
+ return pb_span
95
+
96
+
97
+ def decode(
98
+ pb_span: pb.Span,
99
+ ) -> Span:
100
+ trace_id = UUID(bytes=pb_span.context.trace_id)
101
+ span_id = UUID(bytes=pb_span.context.span_id)
102
+ parent_id = (
103
+ UUID(bytes=pb_span.parent_span_id.value) if pb_span.HasField("parent_span_id") else None
104
+ )
105
+ start_time = pb_span.start_time.ToDatetime(timezone.utc)
106
+ end_time = pb_span.end_time.ToDatetime(timezone.utc) if pb_span.HasField("end_time") else None
107
+ attributes = MessageToDict(pb_span.attributes)
108
+ if pb_span.HasField("input"):
109
+ attributes.update(_decode_input(pb_span.input))
110
+ if pb_span.HasField("output"):
111
+ attributes.update(_decode_output(pb_span.output))
112
+ if pb_span.HasField("retrieval"):
113
+ attributes.update(_decode_retrieval(pb_span.retrieval))
114
+ if pb_span.HasField("embedding"):
115
+ attributes.update(_decode_embedding(pb_span.embedding))
116
+ events = sorted(
117
+ chain(
118
+ map(_decode_event, pb_span.events),
119
+ map(_decode_exception, pb_span.exceptions),
120
+ ),
121
+ key=lambda event: event.timestamp,
122
+ )
123
+ status_code = SpanStatusCode.UNSET
124
+ if pb_span.status.code == pb.Span.Status.Code.OK:
125
+ status_code = SpanStatusCode.OK
126
+ elif pb_span.status.code == pb.Span.Status.Code.ERROR:
127
+ status_code = SpanStatusCode.ERROR
128
+ return Span(
129
+ name=pb_span.name,
130
+ context=SpanContext(trace_id=trace_id, span_id=span_id),
131
+ parent_id=parent_id,
132
+ span_kind=SpanKind(pb_span.kind.upper()),
133
+ start_time=start_time,
134
+ end_time=end_time,
135
+ attributes=attributes,
136
+ status_code=status_code,
137
+ status_message=pb_span.status.message.value,
138
+ conversation=None,
139
+ events=events,
140
+ )
141
+
142
+
143
+ def _excise_input(
144
+ attributes: Mapping[str, Any],
145
+ ) -> Tuple[Optional[pb.Span.IOValue], Dict[str, Any]]:
146
+ _attributes = dict(attributes)
147
+ if not (
148
+ _attributes.keys()
149
+ & {
150
+ INPUT_VALUE,
151
+ INPUT_MIME_TYPE,
152
+ }
153
+ ):
154
+ return None, _attributes
155
+ input_value: Optional[str] = _attributes.pop(INPUT_VALUE, None)
156
+ assert input_value is None or isinstance(
157
+ input_value, str
158
+ ), f"{INPUT_VALUE} must be str, found {type(input_value)}"
159
+ input_mime_type: Optional[MimeType] = _attributes.pop(INPUT_MIME_TYPE, None)
160
+ assert input_mime_type is None or isinstance(
161
+ input_mime_type, MimeType
162
+ ), f"{INPUT_MIME_TYPE} must be MimeType, found {type(input_mime_type)}"
163
+ return (
164
+ _encode_io_value(
165
+ input_value or "",
166
+ input_mime_type,
167
+ ),
168
+ _attributes,
169
+ )
170
+
171
+
172
+ def _excise_output(
173
+ attributes: Mapping[str, Any],
174
+ ) -> Tuple[Optional[pb.Span.IOValue], Dict[str, Any]]:
175
+ _attributes = dict(attributes)
176
+ if not (
177
+ _attributes.keys()
178
+ & {
179
+ OUTPUT_VALUE,
180
+ OUTPUT_MIME_TYPE,
181
+ }
182
+ ):
183
+ return None, _attributes
184
+ output_value: Optional[str] = _attributes.pop(OUTPUT_VALUE, None)
185
+ assert output_value is None or isinstance(
186
+ output_value, str
187
+ ), f"{OUTPUT_VALUE} must be str, found {type(output_value)}"
188
+ output_mime_type: Optional[MimeType] = _attributes.pop(OUTPUT_MIME_TYPE, None)
189
+ assert output_mime_type is None or isinstance(
190
+ output_mime_type, MimeType
191
+ ), f"{OUTPUT_MIME_TYPE} must be MimeType, found {type(output_mime_type)}"
192
+ return (
193
+ _encode_io_value(
194
+ output_value or "",
195
+ output_mime_type,
196
+ ),
197
+ _attributes,
198
+ )
199
+
200
+
201
+ def _excise_retrieval(
202
+ attributes: Mapping[str, Any],
203
+ ) -> Tuple[Optional[pb.Retrieval], Dict[str, Any]]:
204
+ _attributes = dict(attributes)
205
+ if not (
206
+ _attributes.keys()
207
+ & {
208
+ RETRIEVAL_DOCUMENTS,
209
+ }
210
+ ):
211
+ return None, _attributes
212
+ documents: Optional[Iterable[Mapping[str, Any]]] = _attributes.pop(RETRIEVAL_DOCUMENTS, None)
213
+ assert documents is None or isinstance(
214
+ documents, Iterable
215
+ ), f"{RETRIEVAL_DOCUMENTS} must be Iterable, found {type(documents)}"
216
+ return (
217
+ _encode_retrieval(documents=() if documents is None else documents),
218
+ _attributes,
219
+ )
220
+
221
+
222
+ def _excise_embedding(
223
+ attributes: Mapping[str, Any],
224
+ ) -> Tuple[Optional[pb.Embedding], Dict[str, Any]]:
225
+ _attributes = dict(attributes)
226
+ if not (
227
+ _attributes.keys()
228
+ & {
229
+ EMBEDDING_EMBEDDINGS,
230
+ EMBEDDING_MODEL_NAME,
231
+ }
232
+ ):
233
+ return None, _attributes
234
+ embeddings: Optional[Iterable[Mapping[str, Any]]] = _attributes.pop(EMBEDDING_EMBEDDINGS, None)
235
+ assert embeddings is None or isinstance(
236
+ embeddings, Iterable
237
+ ), f"{EMBEDDING_EMBEDDINGS} must be Mapping, found {type(embeddings)}"
238
+ model_name: Optional[str] = _attributes.pop(EMBEDDING_MODEL_NAME, None)
239
+ assert model_name is None or isinstance(
240
+ model_name, str
241
+ ), f"{EMBEDDING_MODEL_NAME} must be str, found {type(model_name)}"
242
+ return (
243
+ _encode_embedding(
244
+ embeddings=embeddings or (),
245
+ model_name=model_name,
246
+ ),
247
+ _attributes,
248
+ )
249
+
250
+
251
+ def _encode_event(
252
+ span_event: SpanEvent,
253
+ ) -> pb.Span.Event:
254
+ timestamp = Timestamp()
255
+ timestamp.FromDatetime(span_event.timestamp)
256
+ attributes = None
257
+ if span_event.attributes:
258
+ attributes = Struct()
259
+ attributes.update(span_event.attributes)
260
+ pb_span_event = pb.Span.Event(
261
+ name=span_event.name,
262
+ timestamp=timestamp,
263
+ attributes=attributes,
264
+ )
265
+ return pb_span_event
266
+
267
+
268
+ def _decode_event(
269
+ pb_span_event: pb.Span.Event,
270
+ ) -> SpanEvent:
271
+ return SpanEvent(
272
+ name=pb_span_event.name,
273
+ timestamp=pb_span_event.timestamp.ToDatetime(timezone.utc),
274
+ attributes=MessageToDict(pb_span_event.attributes),
275
+ )
276
+
277
+
278
+ def _encode_exception(
279
+ span_exception: SpanException,
280
+ ) -> pb.Span.Exception:
281
+ timestamp = Timestamp()
282
+ timestamp.FromDatetime(span_exception.timestamp)
283
+ _attributes: Dict[str, Any] = dict(span_exception.attributes)
284
+ exception_message: Optional[str] = _attributes.pop(EXCEPTION_MESSAGE, None)
285
+ assert exception_message is None or isinstance(
286
+ exception_message, str
287
+ ), f"{EXCEPTION_MESSAGE} must be str, found {type(exception_message)}"
288
+ exception_type: Optional[str] = _attributes.pop(EXCEPTION_TYPE, None)
289
+ assert exception_type is None or isinstance(
290
+ exception_type, str
291
+ ), f"{EXCEPTION_TYPE} must be str, found {type(exception_type)}"
292
+ exception_escaped: Optional[bool] = _attributes.pop(EXCEPTION_ESCAPED, None)
293
+ assert exception_escaped is None or isinstance(
294
+ exception_escaped, bool
295
+ ), f"{EXCEPTION_ESCAPED} must be bool, found {type(exception_escaped)}"
296
+ exception_stacktrace: Optional[str] = _attributes.pop(EXCEPTION_STACKTRACE, None)
297
+ assert exception_stacktrace is None or isinstance(
298
+ exception_stacktrace, str
299
+ ), f"{EXCEPTION_STACKTRACE} must be str, found {type(exception_stacktrace)}"
300
+ pb_span_exception = pb.Span.Exception(
301
+ timestamp=timestamp,
302
+ message=_maybe_str(exception_message),
303
+ type=_maybe_str(exception_type),
304
+ escaped=_maybe_bool(exception_escaped),
305
+ stacktrace=_maybe_str(exception_stacktrace),
306
+ attributes=_maybe_struct(_attributes),
307
+ )
308
+ return pb_span_exception
309
+
310
+
311
+ def _decode_exception(
312
+ pb_span_exception: pb.Span.Exception,
313
+ ) -> SpanException:
314
+ exception_message = (
315
+ pb_span_exception.message.value if pb_span_exception.HasField("message") else None
316
+ )
317
+ exception_type = pb_span_exception.type.value if pb_span_exception.HasField("type") else None
318
+ exception_escaped = (
319
+ pb_span_exception.escaped.value if pb_span_exception.HasField("escaped") else None
320
+ )
321
+ exception_stacktrace = (
322
+ pb_span_exception.stacktrace.value if pb_span_exception.HasField("stacktrace") else None
323
+ )
324
+ span_exception = SpanException(
325
+ timestamp=pb_span_exception.timestamp.ToDatetime(timezone.utc),
326
+ message=exception_message or "",
327
+ exception_type=exception_type,
328
+ exception_escaped=exception_escaped,
329
+ exception_stacktrace=exception_stacktrace,
330
+ )
331
+ span_exception.attributes.update(
332
+ MessageToDict(
333
+ pb_span_exception.attributes,
334
+ ),
335
+ )
336
+ return span_exception
337
+
338
+
339
+ def _decode_input(
340
+ pb_io_value: pb.Span.IOValue,
341
+ ) -> Iterator[Tuple[str, Union[str, MimeType]]]:
342
+ return zip(
343
+ (INPUT_VALUE, INPUT_MIME_TYPE),
344
+ _decode_io_value(pb_io_value),
345
+ )
346
+
347
+
348
+ def _decode_output(
349
+ pb_io_value: pb.Span.IOValue,
350
+ ) -> Iterator[Tuple[str, Union[str, MimeType]]]:
351
+ return zip(
352
+ (OUTPUT_VALUE, OUTPUT_MIME_TYPE),
353
+ _decode_io_value(pb_io_value),
354
+ )
355
+
356
+
357
+ def _encode_io_value(
358
+ io_value: str,
359
+ mime_type: Optional[MimeType],
360
+ ) -> pb.Span.IOValue:
361
+ if mime_type is MimeType.JSON:
362
+ struct = Struct()
363
+ if io_value:
364
+ struct.update(json.loads(io_value))
365
+ return pb.Span.IOValue(json_value=struct)
366
+ return pb.Span.IOValue(string_value=io_value)
367
+
368
+
369
+ def _decode_io_value(
370
+ pb_io_value: pb.Span.IOValue,
371
+ ) -> Iterator[Union[str, MimeType]]:
372
+ if pb_io_value.WhichOneof("kind") == "json_value":
373
+ yield json.dumps(MessageToDict(pb_io_value.json_value))
374
+ yield MimeType.JSON
375
+ else:
376
+ yield pb_io_value.string_value
377
+
378
+
379
+ def _encode_retrieval(
380
+ documents: Iterable[Mapping[str, Any]],
381
+ ) -> pb.Retrieval:
382
+ return pb.Retrieval(
383
+ documents=map(
384
+ _encode_retrieval_document,
385
+ documents,
386
+ ),
387
+ )
388
+
389
+
390
+ def _decode_retrieval(
391
+ pb_retrieval: pb.Retrieval,
392
+ ) -> Iterator[Tuple[str, Any]]:
393
+ yield RETRIEVAL_DOCUMENTS, [
394
+ dict(_decode_retrieval_document(pb_retrieval_document))
395
+ for pb_retrieval_document in pb_retrieval.documents
396
+ ]
397
+
398
+
399
+ def _encode_retrieval_document(
400
+ document: Mapping[str, Any],
401
+ ) -> pb.Retrieval.Document:
402
+ _attributes: Dict[str, Any] = dict(document)
403
+ document_id: Optional[str] = _attributes.pop(DOCUMENT_ID, None)
404
+ assert document_id is None or isinstance(
405
+ document_id, str
406
+ ), f"{DOCUMENT_ID} must be str, found {type(document_id)}"
407
+ document_score: Optional[float] = _attributes.pop(DOCUMENT_SCORE, None)
408
+ assert document_score is None or isinstance(
409
+ document_score, SupportsFloat
410
+ ), f"{DOCUMENT_SCORE} must be float, found {type(document_score)}"
411
+ document_content: Optional[str] = _attributes.pop(DOCUMENT_CONTENT, None)
412
+ assert document_content is None or isinstance(
413
+ document_content, str
414
+ ), f"{DOCUMENT_CONTENT} must be str, found {type(document_content)}"
415
+ document_metadata: Optional[Mapping[str, Any]] = _attributes.pop(DOCUMENT_METADATA, None)
416
+ assert document_metadata is None or isinstance(
417
+ document_metadata, Mapping
418
+ ), f"{DOCUMENT_METADATA} must be Mapping, found {type(document_metadata)}"
419
+ return pb.Retrieval.Document(
420
+ id=_maybe_str(document_id),
421
+ score=_maybe_float(document_score),
422
+ content=_maybe_str(document_content),
423
+ metadata=_maybe_struct(document_metadata),
424
+ attributes=_maybe_struct(_attributes),
425
+ )
426
+
427
+
428
+ def _decode_retrieval_document(
429
+ pb_document: pb.Retrieval.Document,
430
+ ) -> Iterator[Tuple[str, Any]]:
431
+ if pb_document.HasField("id"):
432
+ yield DOCUMENT_ID, pb_document.id.value
433
+ if pb_document.HasField("score"):
434
+ yield DOCUMENT_SCORE, pb_document.score.value
435
+ if pb_document.HasField("content"):
436
+ yield DOCUMENT_CONTENT, pb_document.content.value
437
+ if pb_document.HasField("metadata"):
438
+ yield DOCUMENT_METADATA, MessageToDict(pb_document.metadata)
439
+ if pb_document.HasField("attributes"):
440
+ yield from MessageToDict(pb_document.attributes).items()
441
+
442
+
443
+ def _encode_embedding(
444
+ embeddings: Iterable[Mapping[str, Any]],
445
+ model_name: Optional[str],
446
+ ) -> pb.Embedding:
447
+ return pb.Embedding(
448
+ model_name=_maybe_str(model_name),
449
+ embeddings=map(_encode_embedding_embedding, embeddings),
450
+ )
451
+
452
+
453
+ def _decode_embedding(
454
+ pb_embedding: pb.Embedding,
455
+ ) -> Iterator[Tuple[str, Any]]:
456
+ if pb_embedding.HasField("model_name"):
457
+ yield EMBEDDING_MODEL_NAME, pb_embedding.model_name.value
458
+ yield EMBEDDING_EMBEDDINGS, [
459
+ dict(_decode_embedding_embedding(pb_embedding_embedding))
460
+ for pb_embedding_embedding in pb_embedding.embeddings
461
+ ]
462
+
463
+
464
+ def _encode_embedding_embedding(
465
+ embedding: Mapping[str, Any],
466
+ ) -> pb.Embedding.Embedding:
467
+ _attributes = dict(embedding)
468
+ vector: Optional[Iterable[float]] = _attributes.pop(EMBEDDING_VECTOR, None)
469
+ assert vector is None or isinstance(
470
+ vector, Iterable
471
+ ), f"{EMBEDDING_VECTOR} must be Iterable, found {type(vector)}"
472
+ embedding_text: Optional[str] = _attributes.pop(EMBEDDING_TEXT, None)
473
+ assert embedding_text is None or isinstance(
474
+ embedding_text, str
475
+ ), f"{EMBEDDING_TEXT} must be str, found {type(embedding_text)}"
476
+ return pb.Embedding.Embedding(
477
+ vector=() if vector is None else vector,
478
+ text=_maybe_str(embedding_text),
479
+ attributes=_maybe_struct(_attributes),
480
+ )
481
+
482
+
483
+ def _decode_embedding_embedding(
484
+ pb_embedding_embedding: pb.Embedding.Embedding,
485
+ ) -> Iterator[Tuple[str, Any]]:
486
+ yield EMBEDDING_VECTOR, list(pb_embedding_embedding.vector)
487
+ if pb_embedding_embedding.HasField("text"):
488
+ yield EMBEDDING_TEXT, pb_embedding_embedding.text.value
489
+ if pb_embedding_embedding.HasField("attributes"):
490
+ yield from MessageToDict(pb_embedding_embedding.attributes).items()
491
+
492
+
493
+ def _maybe_str(obj: Optional[str]) -> Optional[StringValue]:
494
+ return None if not obj else StringValue(value=obj)
495
+
496
+
497
+ def _maybe_float(obj: Optional[float]) -> Optional[FloatValue]:
498
+ return None if obj is None else FloatValue(value=obj)
499
+
500
+
501
+ def _maybe_bool(obj: Optional[bool]) -> Optional[BoolValue]:
502
+ return None if obj is None else BoolValue(value=obj)
503
+
504
+
505
+ def _as_timestamp(obj: datetime) -> Timestamp:
506
+ timestamp = Timestamp()
507
+ timestamp.FromDatetime(obj)
508
+ return timestamp
509
+
510
+
511
+ def _maybe_timestamp(obj: Optional[datetime]) -> Optional[Timestamp]:
512
+ return _as_timestamp(obj) if obj else None
513
+
514
+
515
+ def _as_struct(obj: Mapping[str, Any]) -> Struct:
516
+ struct = Struct()
517
+ struct.update(obj)
518
+ return struct
519
+
520
+
521
+ def _maybe_struct(obj: Optional[Mapping[str, Any]]) -> Optional[Struct]:
522
+ return _as_struct(obj) if obj else None
@@ -0,0 +1,52 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: trace/v1/trace.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
15
+ from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
16
+ from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2
17
+
18
+
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14trace/v1/trace.proto\x12\x16phoenix.proto.trace.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xa2\x0b\n\x04Span\x12+\n\nattributes\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x35\n\x07\x63ontext\x18\x02 \x01(\x0b\x32$.phoenix.proto.trace.v1.Span.Context\x12\x33\n\x0eparent_span_id\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.BytesValue\x12\x0c\n\x04name\x18\x04 \x01(\t\x12.\n\nstart_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x33\n\x06status\x18\x07 \x01(\x0b\x32#.phoenix.proto.trace.v1.Span.Status\x12\x32\n\x06\x65vents\x18\x08 \x03(\x0b\x32\".phoenix.proto.trace.v1.Span.Event\x12:\n\nexceptions\x18\t \x03(\x0b\x32&.phoenix.proto.trace.v1.Span.Exception\x12\x33\n\x05input\x18\n \x01(\x0b\x32$.phoenix.proto.trace.v1.Span.IOValue\x12\x34\n\x06output\x18\x0b \x01(\x0b\x32$.phoenix.proto.trace.v1.Span.IOValue\x12\x0c\n\x04kind\x18\x0c \x01(\t\x12\x34\n\tretrieval\x18\r \x01(\x0b\x32!.phoenix.proto.trace.v1.Retrieval\x12\x34\n\tembedding\x18\x0e \x01(\x0b\x32!.phoenix.proto.trace.v1.Embedding\x12(\n\x03llm\x18\x0f \x01(\x0b\x32\x1b.phoenix.proto.trace.v1.LLM\x12*\n\x04tool\x18\x10 \x01(\x0b\x32\x1c.phoenix.proto.trace.v1.Tool\x1a,\n\x07\x43ontext\x12\x10\n\x08trace_id\x18\x01 \x01(\x0c\x12\x0f\n\x07span_id\x18\x02 \x01(\x0c\x1a\x95\x01\n\x06Status\x12\x36\n\x04\x63ode\x18\x01 \x01(\x0e\x32(.phoenix.proto.trace.v1.Span.Status.Code\x12-\n\x07message\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"$\n\x04\x43ode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02OK\x10\x01\x12\t\n\x05\x45RROR\x10\x02\x1aq\n\x05\x45vent\x12+\n\nattributes\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\ttimestamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a\xa1\x02\n\tException\x12+\n\nattributes\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\x07message\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12*\n\x04type\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x07\x65scaped\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x30\n\nstacktrace\x18\x05 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\ttimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1aX\n\x07IOValue\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12-\n\njson_value\x18\x02 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x42\x06\n\x04kind\"\xdf\x02\n\tRetrieval\x12=\n\tdocuments\x18\x01 \x03(\x0b\x32*.phoenix.proto.trace.v1.Retrieval.Document\x1a\x92\x02\n\x08\x44ocument\x12+\n\nattributes\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12(\n\x02id\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12*\n\x05score\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.FloatValue\x12-\n\x07\x63ontent\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x08metadata\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12)\n\x04hash\x18\x06 \x01(\x0b\x32\x1b.google.protobuf.BytesValue\"\xf4\x01\n\tEmbedding\x12?\n\nembeddings\x18\x01 \x03(\x0b\x32+.phoenix.proto.trace.v1.Embedding.Embedding\x12\x30\n\nmodel_name\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x1at\n\tEmbedding\x12+\n\nattributes\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06vector\x18\x02 \x03(\x02\x12*\n\x04text\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"2\n\x03LLM\x12+\n\nattributes\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\"3\n\x04Tool\x12+\n\nattributes\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Structb\x06proto3')
20
+
21
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
22
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'trace.v1.trace_pb2', globals())
23
+ if _descriptor._USE_C_DESCRIPTORS == False:
24
+
25
+ DESCRIPTOR._options = None
26
+ _SPAN._serialized_start=144
27
+ _SPAN._serialized_end=1586
28
+ _SPAN_CONTEXT._serialized_start=893
29
+ _SPAN_CONTEXT._serialized_end=937
30
+ _SPAN_STATUS._serialized_start=940
31
+ _SPAN_STATUS._serialized_end=1089
32
+ _SPAN_STATUS_CODE._serialized_start=1053
33
+ _SPAN_STATUS_CODE._serialized_end=1089
34
+ _SPAN_EVENT._serialized_start=1091
35
+ _SPAN_EVENT._serialized_end=1204
36
+ _SPAN_EXCEPTION._serialized_start=1207
37
+ _SPAN_EXCEPTION._serialized_end=1496
38
+ _SPAN_IOVALUE._serialized_start=1498
39
+ _SPAN_IOVALUE._serialized_end=1586
40
+ _RETRIEVAL._serialized_start=1589
41
+ _RETRIEVAL._serialized_end=1940
42
+ _RETRIEVAL_DOCUMENT._serialized_start=1666
43
+ _RETRIEVAL_DOCUMENT._serialized_end=1940
44
+ _EMBEDDING._serialized_start=1943
45
+ _EMBEDDING._serialized_end=2187
46
+ _EMBEDDING_EMBEDDING._serialized_start=2071
47
+ _EMBEDDING_EMBEDDING._serialized_end=2187
48
+ _LLM._serialized_start=2189
49
+ _LLM._serialized_end=2239
50
+ _TOOL._serialized_start=2241
51
+ _TOOL._serialized_end=2292
52
+ # @@protoc_insertion_point(module_scope)