braintrust 0.3.15__py3-none-any.whl → 0.4.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.
Files changed (82) hide show
  1. braintrust/_generated_types.py +737 -672
  2. braintrust/audit.py +2 -2
  3. braintrust/bt_json.py +178 -19
  4. braintrust/cli/eval.py +6 -7
  5. braintrust/cli/push.py +11 -11
  6. braintrust/context.py +12 -17
  7. braintrust/contrib/temporal/__init__.py +16 -27
  8. braintrust/contrib/temporal/test_temporal.py +8 -3
  9. braintrust/devserver/auth.py +8 -8
  10. braintrust/devserver/cache.py +3 -4
  11. braintrust/devserver/cors.py +8 -7
  12. braintrust/devserver/dataset.py +3 -5
  13. braintrust/devserver/eval_hooks.py +7 -6
  14. braintrust/devserver/schemas.py +22 -19
  15. braintrust/devserver/server.py +19 -12
  16. braintrust/devserver/test_cached_login.py +4 -4
  17. braintrust/framework.py +139 -142
  18. braintrust/framework2.py +88 -87
  19. braintrust/functions/invoke.py +66 -59
  20. braintrust/functions/stream.py +3 -2
  21. braintrust/generated_types.py +3 -1
  22. braintrust/git_fields.py +11 -11
  23. braintrust/gitutil.py +2 -3
  24. braintrust/graph_util.py +10 -10
  25. braintrust/id_gen.py +2 -2
  26. braintrust/logger.py +373 -471
  27. braintrust/merge_row_batch.py +10 -9
  28. braintrust/oai.py +21 -20
  29. braintrust/otel/__init__.py +49 -49
  30. braintrust/otel/context.py +16 -30
  31. braintrust/otel/test_distributed_tracing.py +14 -11
  32. braintrust/otel/test_otel_bt_integration.py +32 -31
  33. braintrust/parameters.py +8 -8
  34. braintrust/prompt.py +14 -14
  35. braintrust/prompt_cache/disk_cache.py +5 -4
  36. braintrust/prompt_cache/lru_cache.py +3 -2
  37. braintrust/prompt_cache/prompt_cache.py +13 -14
  38. braintrust/queue.py +4 -4
  39. braintrust/score.py +4 -4
  40. braintrust/serializable_data_class.py +4 -4
  41. braintrust/span_identifier_v1.py +1 -2
  42. braintrust/span_identifier_v2.py +3 -4
  43. braintrust/span_identifier_v3.py +23 -20
  44. braintrust/span_identifier_v4.py +34 -25
  45. braintrust/test_bt_json.py +644 -0
  46. braintrust/test_framework.py +72 -6
  47. braintrust/test_helpers.py +5 -5
  48. braintrust/test_id_gen.py +2 -3
  49. braintrust/test_logger.py +211 -107
  50. braintrust/test_otel.py +61 -53
  51. braintrust/test_queue.py +0 -1
  52. braintrust/test_score.py +1 -3
  53. braintrust/test_span_components.py +29 -44
  54. braintrust/util.py +9 -8
  55. braintrust/version.py +2 -2
  56. braintrust/wrappers/_anthropic_utils.py +4 -4
  57. braintrust/wrappers/agno/__init__.py +3 -4
  58. braintrust/wrappers/agno/agent.py +1 -2
  59. braintrust/wrappers/agno/function_call.py +1 -2
  60. braintrust/wrappers/agno/model.py +1 -2
  61. braintrust/wrappers/agno/team.py +1 -2
  62. braintrust/wrappers/agno/utils.py +12 -12
  63. braintrust/wrappers/anthropic.py +7 -8
  64. braintrust/wrappers/claude_agent_sdk/__init__.py +3 -4
  65. braintrust/wrappers/claude_agent_sdk/_wrapper.py +29 -27
  66. braintrust/wrappers/dspy.py +15 -17
  67. braintrust/wrappers/google_genai/__init__.py +17 -30
  68. braintrust/wrappers/langchain.py +22 -24
  69. braintrust/wrappers/litellm.py +4 -3
  70. braintrust/wrappers/openai.py +15 -15
  71. braintrust/wrappers/pydantic_ai.py +225 -110
  72. braintrust/wrappers/test_agno.py +0 -1
  73. braintrust/wrappers/test_dspy.py +0 -1
  74. braintrust/wrappers/test_google_genai.py +64 -4
  75. braintrust/wrappers/test_litellm.py +0 -1
  76. braintrust/wrappers/test_pydantic_ai_integration.py +819 -22
  77. {braintrust-0.3.15.dist-info → braintrust-0.4.1.dist-info}/METADATA +3 -2
  78. braintrust-0.4.1.dist-info/RECORD +121 -0
  79. braintrust-0.3.15.dist-info/RECORD +0 -120
  80. {braintrust-0.3.15.dist-info → braintrust-0.4.1.dist-info}/WHEEL +0 -0
  81. {braintrust-0.3.15.dist-info → braintrust-0.4.1.dist-info}/entry_points.txt +0 -0
  82. {braintrust-0.3.15.dist-info → braintrust-0.4.1.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,7 @@ Exports `BraintrustTracingProcessor`, a `tracing.TracingProcessor` that logs tra
3
3
  """
4
4
 
5
5
  import datetime
6
- from typing import Any, Dict, Optional, Union
6
+ from typing import Any
7
7
 
8
8
  import braintrust
9
9
  from agents import tracing
@@ -40,13 +40,13 @@ def _span_name(span: tracing.Span[Any]) -> str:
40
40
  return "Unknown"
41
41
 
42
42
 
43
- def _timestamp_from_maybe_iso(timestamp: Optional[str]) -> Optional[float]:
43
+ def _timestamp_from_maybe_iso(timestamp: str | None) -> float | None:
44
44
  if timestamp is None:
45
45
  return None
46
46
  return datetime.datetime.fromisoformat(timestamp).timestamp()
47
47
 
48
48
 
49
- def _maybe_timestamp_elapsed(end: Optional[str], start: Optional[str]) -> Optional[float]:
49
+ def _maybe_timestamp_elapsed(end: str | None, start: str | None) -> float | None:
50
50
  if start is None or end is None:
51
51
  return None
52
52
  return (datetime.datetime.fromisoformat(end) - datetime.datetime.fromisoformat(start)).total_seconds()
@@ -61,11 +61,11 @@ class BraintrustTracingProcessor(tracing.TracingProcessor):
61
61
  If `None`, the current span, experiment, or logger will be selected exactly as in `braintrust.start_span`.
62
62
  """
63
63
 
64
- def __init__(self, logger: Optional[Union[braintrust.Span, braintrust.Experiment, braintrust.Logger]] = None):
64
+ def __init__(self, logger: braintrust.Span | braintrust.Experiment | braintrust.Logger | None = None):
65
65
  self._logger = logger
66
- self._spans: Dict[str, braintrust.Span] = {}
67
- self._first_input: Dict[str, Any] = {}
68
- self._last_output: Dict[str, Any] = {}
66
+ self._spans: dict[str, braintrust.Span] = {}
67
+ self._first_input: dict[str, Any] = {}
68
+ self._last_output: dict[str, Any] = {}
69
69
 
70
70
  def on_trace_start(self, trace: tracing.Trace) -> None:
71
71
  trace_meta = trace.export() or {}
@@ -113,7 +113,7 @@ class BraintrustTracingProcessor(tracing.TracingProcessor):
113
113
  # TODO(sachin): Add end time when SDK provides it.
114
114
  # span.end(_timestamp_from_maybe_iso(trace.ended_at))
115
115
 
116
- def _agent_log_data(self, span: tracing.Span[tracing.AgentSpanData]) -> Dict[str, Any]:
116
+ def _agent_log_data(self, span: tracing.Span[tracing.AgentSpanData]) -> dict[str, Any]:
117
117
  return {
118
118
  "metadata": {
119
119
  "tools": span.span_data.tools,
@@ -122,7 +122,7 @@ class BraintrustTracingProcessor(tracing.TracingProcessor):
122
122
  }
123
123
  }
124
124
 
125
- def _response_log_data(self, span: tracing.Span[tracing.ResponseSpanData]) -> Dict[str, Any]:
125
+ def _response_log_data(self, span: tracing.Span[tracing.ResponseSpanData]) -> dict[str, Any]:
126
126
  data = {}
127
127
  if span.span_data.input is not None:
128
128
  data["input"] = span.span_data.input
@@ -145,13 +145,13 @@ class BraintrustTracingProcessor(tracing.TracingProcessor):
145
145
 
146
146
  return data
147
147
 
148
- def _function_log_data(self, span: tracing.Span[tracing.FunctionSpanData]) -> Dict[str, Any]:
148
+ def _function_log_data(self, span: tracing.Span[tracing.FunctionSpanData]) -> dict[str, Any]:
149
149
  return {
150
150
  "input": span.span_data.input,
151
151
  "output": span.span_data.output,
152
152
  }
153
153
 
154
- def _handoff_log_data(self, span: tracing.Span[tracing.HandoffSpanData]) -> Dict[str, Any]:
154
+ def _handoff_log_data(self, span: tracing.Span[tracing.HandoffSpanData]) -> dict[str, Any]:
155
155
  return {
156
156
  "metadata": {
157
157
  "from_agent": span.span_data.from_agent,
@@ -159,14 +159,14 @@ class BraintrustTracingProcessor(tracing.TracingProcessor):
159
159
  }
160
160
  }
161
161
 
162
- def _guardrail_log_data(self, span: tracing.Span[tracing.GuardrailSpanData]) -> Dict[str, Any]:
162
+ def _guardrail_log_data(self, span: tracing.Span[tracing.GuardrailSpanData]) -> dict[str, Any]:
163
163
  return {
164
164
  "metadata": {
165
165
  "triggered": span.span_data.triggered,
166
166
  }
167
167
  }
168
168
 
169
- def _generation_log_data(self, span: tracing.Span[tracing.GenerationSpanData]) -> Dict[str, Any]:
169
+ def _generation_log_data(self, span: tracing.Span[tracing.GenerationSpanData]) -> dict[str, Any]:
170
170
  metrics = {}
171
171
  ttft = _maybe_timestamp_elapsed(span.ended_at, span.started_at)
172
172
 
@@ -199,10 +199,10 @@ class BraintrustTracingProcessor(tracing.TracingProcessor):
199
199
  "metrics": metrics,
200
200
  }
201
201
 
202
- def _custom_log_data(self, span: tracing.Span[tracing.CustomSpanData]) -> Dict[str, Any]:
202
+ def _custom_log_data(self, span: tracing.Span[tracing.CustomSpanData]) -> dict[str, Any]:
203
203
  return span.span_data.data
204
204
 
205
- def _log_data(self, span: tracing.Span[Any]) -> Dict[str, Any]:
205
+ def _log_data(self, span: tracing.Span[Any]) -> dict[str, Any]:
206
206
  if isinstance(span.span_data, tracing.AgentSpanData):
207
207
  return self._agent_log_data(span)
208
208
  elif isinstance(span.span_data, tracing.ResponseSpanData):