braintrust 0.4.2__py3-none-any.whl → 0.4.3__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.
@@ -0,0 +1,338 @@
1
+ # pyright: reportPrivateUsage=false
2
+ # pyright: reportMissingParameterType=false
3
+ # pyright: reportUnknownParameterType=false
4
+ # pyright: reportUnknownArgumentType=false
5
+ # pyright: reportUnknownMemberType=false
6
+ # pylint: disable=protected-access
7
+
8
+ """
9
+ Tests for the LangSmith wrapper to ensure compatibility with LangSmith's API.
10
+ """
11
+
12
+
13
+ from braintrust.wrappers.langsmith_wrapper import (
14
+ _convert_langsmith_data,
15
+ _is_patched,
16
+ _make_braintrust_scorer,
17
+ _make_braintrust_task,
18
+ wrap_aevaluate,
19
+ wrap_client,
20
+ wrap_traceable,
21
+ )
22
+
23
+
24
+ def test_is_patched_false():
25
+ """Test that _is_patched returns False for unpatched objects."""
26
+
27
+ def unpatched():
28
+ pass
29
+
30
+ assert _is_patched(unpatched) is False
31
+
32
+
33
+ def test_is_patched_true():
34
+ """Test that _is_patched returns True for patched objects."""
35
+
36
+ def patched():
37
+ pass
38
+
39
+ patched._braintrust_patched = True # type: ignore
40
+
41
+ assert _is_patched(patched) is True
42
+
43
+
44
+ def test_make_braintrust_scorer_dict_result():
45
+ """Test converting a LangSmith evaluator that returns a dict."""
46
+
47
+ def langsmith_evaluator(inputs, outputs, reference_outputs):
48
+ return {"key": "accuracy", "score": 0.9, "metadata": {"note": "good"}}
49
+
50
+ converted = _make_braintrust_scorer(langsmith_evaluator)
51
+
52
+ # Create a mock Example object
53
+ class MockExample:
54
+ outputs = {"y": 2}
55
+
56
+ result = converted(input={"x": 1}, output={"y": 2}, expected=MockExample())
57
+
58
+ assert result.name == "accuracy"
59
+ assert result.score == 0.9
60
+ assert result.metadata == {"note": "good"}
61
+
62
+
63
+ def test_make_braintrust_scorer_numeric_result():
64
+ """Test converting a LangSmith evaluator that returns a numeric score in a dict."""
65
+
66
+ def langsmith_evaluator(inputs, outputs, reference_outputs):
67
+ return {"score": 1.0 if outputs == reference_outputs else 0.0}
68
+
69
+ converted = _make_braintrust_scorer(langsmith_evaluator)
70
+
71
+ class MockExample:
72
+ outputs = {"y": 2}
73
+
74
+ result = converted(input={"x": 1}, output={"y": 2}, expected=MockExample())
75
+
76
+ assert result.name == "langsmith_evaluator"
77
+ assert result.score == 1.0
78
+
79
+
80
+ def test_make_braintrust_scorer_with_plain_dict_expected():
81
+ """Test converting a LangSmith evaluator with plain dict as expected."""
82
+
83
+ def langsmith_evaluator(inputs, outputs, reference_outputs):
84
+ return {"score": 1.0 if outputs == reference_outputs else 0.0}
85
+
86
+ converted = _make_braintrust_scorer(langsmith_evaluator)
87
+ result = converted(input={"x": 1}, output={"y": 2}, expected={"y": 2})
88
+
89
+ assert result.name == "langsmith_evaluator"
90
+ assert result.score == 1.0
91
+
92
+
93
+ def test_convert_langsmith_data_from_list():
94
+ """Test converting LangSmith data from a list of dicts."""
95
+ data = [
96
+ {"inputs": {"x": 1}, "outputs": {"y": 2}},
97
+ {"inputs": {"x": 2}, "outputs": {"y": 4}},
98
+ ]
99
+
100
+ data_fn = _convert_langsmith_data(data)
101
+ result = list(data_fn())
102
+
103
+ assert len(result) == 2
104
+ assert result[0].input == {"x": 1}
105
+ # The whole item is passed as expected
106
+ assert result[0].expected == {"inputs": {"x": 1}, "outputs": {"y": 2}}
107
+ assert result[1].input == {"x": 2}
108
+ assert result[1].expected == {"inputs": {"x": 2}, "outputs": {"y": 4}}
109
+
110
+
111
+ def test_convert_langsmith_data_from_callable():
112
+ """Test converting LangSmith data from a callable."""
113
+
114
+ def data_generator():
115
+ yield {"inputs": {"x": 1}, "outputs": {"y": 2}}
116
+ yield {"inputs": {"x": 2}, "outputs": {"y": 4}}
117
+
118
+ data_fn = _convert_langsmith_data(data_generator)
119
+ result = list(data_fn())
120
+
121
+ assert len(result) == 2
122
+ assert result[0].input == {"x": 1}
123
+ # The whole item is passed as expected
124
+ assert result[0].expected == {"inputs": {"x": 1}, "outputs": {"y": 2}}
125
+
126
+
127
+ def test_convert_langsmith_data_with_example_objects():
128
+ """Test converting LangSmith data with Example-like objects."""
129
+
130
+ class MockExample:
131
+ def __init__(self, inputs, outputs):
132
+ self.inputs = inputs
133
+ self.outputs = outputs
134
+
135
+ data = [
136
+ MockExample(inputs={"x": 1}, outputs={"y": 2}),
137
+ MockExample(inputs={"x": 2}, outputs={"y": 4}),
138
+ ]
139
+
140
+ data_fn = _convert_langsmith_data(data)
141
+ result = list(data_fn())
142
+
143
+ assert len(result) == 2
144
+ assert result[0].input == {"x": 1}
145
+ # The whole Example object is passed as expected
146
+ assert result[0].expected.inputs == {"x": 1}
147
+ assert result[0].expected.outputs == {"y": 2}
148
+
149
+
150
+ def test_make_braintrust_task_with_dict_input():
151
+ """Test that task function handles dict inputs correctly."""
152
+
153
+ def target_fn(inputs):
154
+ return inputs["x"] * 2
155
+
156
+ task = _make_braintrust_task(target_fn)
157
+ result = task({"x": 5}, None)
158
+
159
+ assert result == 10
160
+
161
+
162
+ def test_make_braintrust_task_with_kwargs_expansion():
163
+ """Test that task function expands dict kwargs when signature matches."""
164
+
165
+ def target_fn(x, y):
166
+ return x + y
167
+
168
+ task = _make_braintrust_task(target_fn)
169
+ result = task({"x": 2, "y": 3}, None)
170
+
171
+ assert result == 5
172
+
173
+
174
+ def test_make_braintrust_task_simple_input():
175
+ """Test that task function handles simple inputs."""
176
+
177
+ def target_fn(inp):
178
+ return inp * 2
179
+
180
+ task = _make_braintrust_task(target_fn)
181
+ result = task(5, None)
182
+
183
+ assert result == 10
184
+
185
+
186
+ class TestWrapTraceable:
187
+ """Tests for wrap_traceable functionality."""
188
+
189
+ def test_wrap_traceable_returns_wrapper(self):
190
+ """Test that wrap_traceable returns a wrapped version."""
191
+
192
+ def mock_traceable(func, **kwargs):
193
+ return func
194
+
195
+ wrapped = wrap_traceable(mock_traceable, standalone=False)
196
+ assert callable(wrapped)
197
+ assert _is_patched(wrapped)
198
+
199
+ def test_wrap_traceable_standalone_mode(self):
200
+ """Test that wrap_traceable works in standalone mode."""
201
+
202
+ def mock_traceable(func, **kwargs):
203
+ return func
204
+
205
+ wrapped = wrap_traceable(mock_traceable, standalone=True)
206
+ assert callable(wrapped)
207
+ assert _is_patched(wrapped)
208
+
209
+
210
+ class TestWrapFunctions:
211
+ """Tests for the wrap_* functions."""
212
+
213
+ def test_wrap_functions_exist(self):
214
+ """Test that wrap functions are callable."""
215
+ assert callable(wrap_traceable)
216
+ assert callable(wrap_client)
217
+ assert callable(wrap_aevaluate)
218
+
219
+ def test_wrap_traceable_returns_patched_function(self):
220
+ """Test that wrap_traceable returns a patched function."""
221
+
222
+ def mock_traceable(func, **kwargs):
223
+ return func
224
+
225
+ wrapped = wrap_traceable(mock_traceable)
226
+ assert _is_patched(wrapped)
227
+
228
+ def test_wrap_traceable_skips_if_already_patched(self):
229
+ """Test that wrap_traceable skips if already patched."""
230
+
231
+ def mock_traceable(func, **kwargs):
232
+ return func
233
+
234
+ mock_traceable._braintrust_patched = True # type: ignore
235
+
236
+ result = wrap_traceable(mock_traceable)
237
+ # Should return the same function
238
+ assert result is mock_traceable
239
+
240
+ def test_wrap_client_sets_flag(self):
241
+ """Test that wrap_client sets the patched flag."""
242
+
243
+ class MockClient:
244
+ def evaluate(self, *args, **kwargs):
245
+ return "original"
246
+
247
+ wrap_client(MockClient)
248
+ assert _is_patched(MockClient.evaluate)
249
+
250
+ def test_wrap_aevaluate_returns_patched_function(self):
251
+ """Test that wrap_aevaluate returns a patched function."""
252
+
253
+ async def mock_aevaluate(*args, **kwargs):
254
+ pass
255
+
256
+ wrapped = wrap_aevaluate(mock_aevaluate)
257
+ assert _is_patched(wrapped)
258
+
259
+
260
+ class TestTandemModeIntegration:
261
+ """Integration tests for tandem mode (LangSmith + Braintrust together)."""
262
+
263
+ def test_make_braintrust_task_with_inputs_parameter(self):
264
+ """Test that task handles LangSmith's required 'inputs' parameter name."""
265
+
266
+ def target_fn(inputs: dict) -> dict:
267
+ return {"result": inputs["x"] * 2}
268
+
269
+ task = _make_braintrust_task(target_fn)
270
+ result = task({"x": 5}, None)
271
+
272
+ assert result == {"result": 10}
273
+
274
+ def test_convert_langsmith_data_handles_different_output_types(self):
275
+ """Test that data conversion handles various output types."""
276
+ data = [
277
+ {"inputs": {"x": 1}, "outputs": 2}, # outputs is int, not dict
278
+ {"inputs": {"x": 2}, "outputs": {"result": 4}}, # outputs is already dict
279
+ ]
280
+
281
+ data_fn = _convert_langsmith_data(data)
282
+ result = list(data_fn())
283
+
284
+ # Both should work - Braintrust's EvalCase accepts any type for expected
285
+ assert len(result) == 2
286
+ assert result[0].input == {"x": 1}
287
+ assert result[1].input == {"x": 2}
288
+
289
+ def test_make_braintrust_scorer_handles_wrapped_outputs(self):
290
+ """Test that scorers handle output wrapping correctly."""
291
+
292
+ def langsmith_evaluator(inputs, outputs, reference_outputs):
293
+ # outputs will be wrapped as {"output": value} for non-dict results
294
+ actual = outputs.get("output", outputs)
295
+ expected = reference_outputs.get("output", reference_outputs) if isinstance(reference_outputs, dict) else reference_outputs
296
+ return {"key": "match", "score": 1.0 if actual == expected else 0.0}
297
+
298
+ converted = _make_braintrust_scorer(langsmith_evaluator)
299
+
300
+ class MockExample:
301
+ outputs = {"output": 42}
302
+
303
+ # Test with wrapped output
304
+ result = converted(input={"x": 1}, output=42, expected=MockExample())
305
+ assert result.name == "match"
306
+ assert result.score == 1.0
307
+
308
+
309
+ class TestDataConversion:
310
+ """Tests for data conversion utilities."""
311
+
312
+ def test_convert_data_with_braintrust_format(self):
313
+ """Test that Braintrust format is properly handled."""
314
+ data = [
315
+ {"input": {"x": 1}, "expected": {"y": 2}},
316
+ {"input": {"x": 2}, "expected": {"y": 4}},
317
+ ]
318
+
319
+ data_fn = _convert_langsmith_data(data)
320
+ result = list(data_fn())
321
+
322
+ assert len(result) == 2
323
+ assert result[0].input == {"x": 1}
324
+ assert result[0].expected == {"y": 2}
325
+ assert result[1].input == {"x": 2}
326
+ assert result[1].expected == {"y": 4}
327
+
328
+ def test_convert_data_with_simple_items(self):
329
+ """Test that simple items (not dicts) are handled."""
330
+ data = [1, 2, 3]
331
+
332
+ data_fn = _convert_langsmith_data(data)
333
+ result = list(data_fn())
334
+
335
+ assert len(result) == 3
336
+ assert result[0].input == 1
337
+ assert result[1].input == 2
338
+ assert result[2].input == 3
@@ -15,16 +15,6 @@ TEST_PROMPT = "What's 12 + 12?"
15
15
  TEST_SYSTEM_PROMPT = "You are a helpful assistant that only responds with numbers."
16
16
 
17
17
 
18
- @pytest.fixture(scope="module")
19
- def vcr_config():
20
- return {
21
- "filter_headers": [
22
- "authorization",
23
- "openai-organization",
24
- ]
25
- }
26
-
27
-
28
18
  @pytest.fixture
29
19
  def memory_logger():
30
20
  init_test_logger(PROJECT_NAME)
@@ -11,16 +11,6 @@ PROJECT_NAME = "test-project-openai-attachment-processing"
11
11
  TEST_MODEL = "gpt-4o-mini"
12
12
 
13
13
 
14
- @pytest.fixture(scope="module")
15
- def vcr_config():
16
- return {
17
- "filter_headers": [
18
- "authorization",
19
- "openai-organization",
20
- ]
21
- }
22
-
23
-
24
14
  @pytest.fixture
25
15
  def memory_logger():
26
16
  init_test_logger(PROJECT_NAME)
@@ -18,16 +18,6 @@ TEST_PROMPT = "What's 12 + 12?"
18
18
  TEST_SYSTEM_PROMPT = "You are a helpful assistant that only responds with numbers."
19
19
 
20
20
 
21
- @pytest.fixture(scope="module")
22
- def vcr_config():
23
- return {
24
- "filter_headers": [
25
- "authorization",
26
- "openai-organization",
27
- ]
28
- }
29
-
30
-
31
21
  @pytest.fixture
32
22
  def memory_logger():
33
23
  init_test_logger(PROJECT_NAME)
@@ -943,8 +933,6 @@ async def test_openai_streaming_with_break(memory_logger):
943
933
  model=TEST_MODEL, messages=[{"role": "user", "content": TEST_PROMPT}], stream=True
944
934
  )
945
935
 
946
- time.sleep(0.2) # time to first token sleep
947
-
948
936
  # Only process the first few chunks
949
937
  counter = 0
950
938
  async for chunk in stream:
@@ -1331,6 +1319,7 @@ def _is_wrapped(client):
1331
1319
 
1332
1320
 
1333
1321
  @pytest.mark.asyncio
1322
+ @pytest.mark.vcr
1334
1323
  async def test_braintrust_tracing_processor_current_span_detection(memory_logger):
1335
1324
  """Test that BraintrustTracingProcessor currentSpan() detection works with OpenAI Agents SDK."""
1336
1325
  pytest.importorskip("agents", reason="agents package not available")
@@ -1440,6 +1429,7 @@ async def test_braintrust_tracing_processor_current_span_detection(memory_logger
1440
1429
 
1441
1430
 
1442
1431
  @pytest.mark.asyncio
1432
+ @pytest.mark.vcr
1443
1433
  async def test_braintrust_tracing_processor_concurrency_bug(memory_logger):
1444
1434
  """Test that reproduces the concurrency bug where overlapping traces mix up first_input/last_output."""
1445
1435
  pytest.importorskip("agents", reason="agents package not available")
@@ -1546,6 +1536,7 @@ async def test_braintrust_tracing_processor_concurrency_bug(memory_logger):
1546
1536
 
1547
1537
 
1548
1538
  @pytest.mark.asyncio
1539
+ @pytest.mark.vcr
1549
1540
  async def test_agents_tool_openai_nested_spans(memory_logger):
1550
1541
  """Test that OpenAI calls inside agent tools are properly nested under the tool span."""
1551
1542
  pytest.importorskip("agents", reason="agents package not available")
@@ -19,15 +19,6 @@ PROJECT_NAME = "test-openrouter"
19
19
  TEST_MODEL = "openai/gpt-4o-mini"
20
20
 
21
21
 
22
- @pytest.fixture(scope="module")
23
- def vcr_config():
24
- return {
25
- "filter_headers": [
26
- "authorization",
27
- ]
28
- }
29
-
30
-
31
22
  @pytest.fixture
32
23
  def memory_logger():
33
24
  init_test_logger(PROJECT_NAME)
@@ -32,17 +32,6 @@ def direct():
32
32
  return direct_module
33
33
 
34
34
 
35
- @pytest.fixture(scope="module")
36
- def vcr_config():
37
- return {
38
- "filter_headers": [
39
- "authorization",
40
- "openai-organization",
41
- "x-api-key",
42
- ]
43
- }
44
-
45
-
46
35
  @pytest.fixture
47
36
  def memory_logger():
48
37
  init_test_logger(PROJECT_NAME)
@@ -66,6 +66,7 @@ def _assert_metrics_are_valid(metrics: Dict[str, Any]):
66
66
  assert "time_to_first_token" in metrics
67
67
 
68
68
 
69
+ @pytest.mark.vcr
69
70
  @pytest.mark.asyncio
70
71
  async def test_pydantic_wrapped_stream(memory_logger):
71
72
  """Test that Pydantic AI streaming operations work with Braintrust wrapping."""
@@ -108,6 +109,7 @@ async def test_pydantic_wrapped_stream(memory_logger):
108
109
  assert span["root_span_id"]
109
110
 
110
111
 
112
+ @pytest.mark.vcr
111
113
  @pytest.mark.asyncio
112
114
  async def test_pydantic_wrapped_completion(memory_logger):
113
115
  """Test that Pydantic AI completion operations work with Braintrust wrapping."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braintrust
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: SDK for integrating Braintrust
5
5
  Home-page: https://www.braintrust.dev
6
6
  Author: Braintrust
@@ -1,20 +1,20 @@
1
1
  braintrust/__init__.py,sha256=sw6dLIINeyUVP4IbF49wqXv2cyAWEoO3SGSIvCb_b2o,2238
2
- braintrust/_generated_types.py,sha256=k36Qyd3AkTMXA_EJLyj0_zrUJTa7VIJDAQCNPbiIbL8,93868
2
+ braintrust/_generated_types.py,sha256=kZs5K7dglu5S-NYztq0RO-uM5Z-Ng-8qHzebYNzStVg,96835
3
3
  braintrust/audit.py,sha256=3GQKzuTcFquYdrJtABM-k3xMlOIqgVkfG6UyeQ8_028,461
4
4
  braintrust/aws.py,sha256=OBz_SRyopgpCDSNvETLypzGwTXk-bNLn-Eisevnjfwo,377
5
5
  braintrust/bt_json.py,sha256=VNunedFUEfbvVEBuACHLRsjDr8lLD3_nFwB54MXtcbY,9385
6
- braintrust/conftest.py,sha256=hopKH5M5ts7DXlvRD_P2b94uXTT7vPKNhBWUdoIetL8,1681
6
+ braintrust/conftest.py,sha256=cmuwhK0BvqZ6yGqD_3x_JJmWkCtaSOwfSKz6n8ZT5Ug,2339
7
7
  braintrust/context.py,sha256=bOo1Li29lUsi2DOOllIDar0oRuQNbkLNzJ7cYq5JTbo,4126
8
8
  braintrust/db_fields.py,sha256=vjVEyDxl2d13lvvTcVwT5paHvaT-1kgI-4Lg-gihRIw,476
9
9
  braintrust/framework.py,sha256=U2ubFkX6LS-3iArMT4sRG17oZa0ClM4GVpC0O8xotxQ,57593
10
10
  braintrust/framework2.py,sha256=o0igz4vXbmn0jHJPhDYvx14rFnI3ntV8H6VJfyJYRtM,16542
11
- braintrust/generated_types.py,sha256=foqHolHkcqYTNL5tfAR0mRIAtOO8Jl4R022QQqe-M1k,4849
11
+ braintrust/generated_types.py,sha256=rzGVd_yajhEXZ-MME3ZWB7UCRvdVx2oANvxDcjKoZA4,4849
12
12
  braintrust/git_fields.py,sha256=au5ayyuvt7y_ojE9LC98ypTZd3RgFdjhRc8eFxcjnto,1434
13
13
  braintrust/gitutil.py,sha256=RsW7cawJMgaAaTw6WeB1sShyfflkPb7yH2x7yuRv10c,5642
14
14
  braintrust/graph_util.py,sha256=Z2Uy8RaOq5iMe5mShhQqRDDIpXVitE-biVxDiFB-0Ds,5545
15
15
  braintrust/http_headers.py,sha256=9ZsDcsAKG04SGowsgchZktD6rG_oSTKWa8QyGUPA4xE,154
16
16
  braintrust/id_gen.py,sha256=4UWLWRhksf76IkYi4cKACSaQ3yNgausrMRlhiurhy74,1590
17
- braintrust/logger.py,sha256=UuTETw0JeNBtKX2OJlM_GlzUyCKPg7Ar1DdVULhl_E4,205548
17
+ braintrust/logger.py,sha256=_kpQni3_TTjnz1bcGJphwe_0xPcAuwxQDsccur6G5Z0,205378
18
18
  braintrust/merge_row_batch.py,sha256=tvuz3qdsa7HZBrzzAzoQqAXU7pKsHUebC7sw6RybbmA,9881
19
19
  braintrust/oai.py,sha256=AjHeD0uNYO-ECVUh9RbPBxyKMps06A3dvHAWa41prMc,36259
20
20
  braintrust/object.py,sha256=vYLyYWncsqLD00zffZUJwGTSkcJF9IIXmgIzrx3Np5c,632
@@ -29,8 +29,8 @@ braintrust/span_identifier_v1.py,sha256=eR-dHda0MurdOlghv7-CLSh7eVpNQigbDSQxPpLC
29
29
  braintrust/span_identifier_v2.py,sha256=2dLc-Vz8iWLISmL_-ebCyWnY-ysA7sMnBsQtKqzMHYY,8981
30
30
  braintrust/span_identifier_v3.py,sha256=l_W8amV0u89X-cHqIhWQdjLZcoeWhwJoAEdYWgCN1nM,9720
31
31
  braintrust/span_identifier_v4.py,sha256=uFT-OdzySo4uCeAaJC3VqH55Oy433xZGBdK2hiEsm2w,10044
32
- braintrust/span_types.py,sha256=UvuyjfL_Delao14TJs9IjnpYLcgDSodKJfAYju01aXQ,292
33
- braintrust/test_bt_json.py,sha256=iixyk_7QIKiF3VVThD9oiWzAT1b-t2fHPYECmSB8VT0,25304
32
+ braintrust/span_types.py,sha256=cpTzCwUj4yBPbPLnzR23-VXIU2E9nl_dsVCSVMvtSkc,376
33
+ braintrust/test_bt_json.py,sha256=p4r5DlMkH2rRQbYT9X1ASPbKVEMku5bFUUa7hVAO-ZY,25259
34
34
  braintrust/test_framework.py,sha256=7spRLovwNjZLula8mNW_KspyWuWgpqSfHV6sZqub-ME,17664
35
35
  braintrust/test_framework2.py,sha256=pSEEmBIyszAiYnpEVvDZgJqIe3lQ3T807LmIuBqV98w,7235
36
36
  braintrust/test_helpers.py,sha256=VSelzjkR2IHyy5QD6sYB_79VIXq-wEDslDwyx9H11kI,13528
@@ -44,14 +44,14 @@ braintrust/test_span_components.py,sha256=6w0oDnDLuVbHygNienujk4JDqtSRR5A49AI-S8
44
44
  braintrust/test_util.py,sha256=xMN84ERVzZYUTAOp0IkFK-ktWOLK4rr6OdhaNeq7Fg0,6382
45
45
  braintrust/test_version.py,sha256=hk5JKjEFbNJ_ONc1VEkqHquflzre34RpFhCEYLTK8iA,1051
46
46
  braintrust/util.py,sha256=-q73F17BkaUaDCGtNBTtacqIPwWiXcgWYpzHqFTQdhc,8361
47
- braintrust/version.py,sha256=8d_QVXySfoJqVPmORR9pWGmW5J1QcpfY-Cp9MlqpGC4,117
47
+ braintrust/version.py,sha256=xijckaJ6-1Mn0R0hTRi55lSGRv3JudT78ygiljJCeaU,117
48
48
  braintrust/xact_ids.py,sha256=bdyp88HjlyIkglgLSqYlCYscdSH6EWVyE14sR90Xl1s,658
49
49
  braintrust/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
50
  braintrust/cli/__main__.py,sha256=wCBKHGVmn3IT_yMXk5qfDwyI2SV2gf1tLr0NTxm9T8k,1519
51
51
  braintrust/cli/eval.py,sha256=ymnCVkZ6mefDBDHO1wqd0IPtBjib-vW_4OTZRWh8sbE,13246
52
52
  braintrust/cli/push.py,sha256=vUbKirxpiaCDYkFx3mskexaFWhczS4eIXKUDZPo5P9s,12423
53
53
  braintrust/cli/install/__init__.py,sha256=scF_YM4dZJ47kT6VlM2CgM9jrEzqEHqPxS88nyVAsfk,1331
54
- braintrust/cli/install/api.py,sha256=Q5XgKlnV1AaZmOI4Sg8Bl9JW_8ILd2Nn_0CvTkDjtqc,18529
54
+ braintrust/cli/install/api.py,sha256=--wjZ0kV9s6TD_OYqljNGYYuLo1u17zRnG7vZ5I-WuE,18528
55
55
  braintrust/cli/install/bump_versions.py,sha256=Wcn6tAXTVz6RcCUg87xxxA-VUeUE8MTSQpOdjQJSz6k,1691
56
56
  braintrust/cli/install/logs.py,sha256=XROIpFp-KS1as1sqZBYwbCF4HogoPV2-m9yBooUjGFI,3740
57
57
  braintrust/cli/install/redshift.py,sha256=MsjN4MW_us_KTWy_YMRK3G5-2Gxd65L2SgI3uO7g-uw,6857
@@ -69,10 +69,10 @@ braintrust/devserver/schemas.py,sha256=Nwms8IzGyo60G5Az0IqZnCbqPmHUzublZvwT3IwcG
69
69
  braintrust/devserver/server.py,sha256=352s7kWxMljs2BcQoCu8rRuBFKek68uHdV5XHt87x2c,12626
70
70
  braintrust/devserver/test_cached_login.py,sha256=-khNsDAuHrO7N-Rt1orIAE_kxTBjfmIGTVyXmw2p6IU,3741
71
71
  braintrust/devserver/test_lru_cache.py,sha256=5YYJ5uFj7k4Z4PQQ-UOV7bLP5zBYVo-5jV5_hpthtgM,4164
72
- braintrust/devserver/test_server_integration.py,sha256=ygIYDsTCSqwa_rzQDtdX0mjkXQVy7qyJjntdoCgtjKM,6711
72
+ braintrust/devserver/test_server_integration.py,sha256=7QhanUNsx7MYdhEL9AOr_ZrQJdSVIN1IorZ_JvIJq5Y,6485
73
73
  braintrust/functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
74
  braintrust/functions/constants.py,sha256=g_EDiSrfCltHr5QaQMQzJ3qy3D29X-11LanDqlicqB0,23
75
- braintrust/functions/invoke.py,sha256=BZQv5FXjLvT1nlPRBhEQv4MSKRVZPSunn63pm1vdkRs,10096
75
+ braintrust/functions/invoke.py,sha256=5lmCUZ4_FPAVOelHuvMmIMQTQXYaqxYeaymptEs69n8,9731
76
76
  braintrust/functions/stream.py,sha256=zH3okhkbUBE3-iYD6edLqjDdewc1Zj1MjVx5A3Xwe9Y,6103
77
77
  braintrust/otel/__init__.py,sha256=sZxGs2khKfL9uFJtB118VJJ7O5QOZJSG3vuKUFB0fiE,24350
78
78
  braintrust/otel/context.py,sha256=EpGk3B1UeAfBeqDe-yYy4LNNCFBKU6aU-0tfVOMrkcs,4611
@@ -82,7 +82,7 @@ braintrust/prompt_cache/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
82
82
  braintrust/prompt_cache/disk_cache.py,sha256=RH20RwKR1lkGMYtMs6oVht6EdBHT0vokq3Z8iOd4jgk,5643
83
83
  braintrust/prompt_cache/lru_cache.py,sha256=us4jyznEeScEUDLXfDyaYY6gSUmUba55Kg-P6fBrtm8,2509
84
84
  braintrust/prompt_cache/prompt_cache.py,sha256=2eA5lc5_5gYJEccA8fFGJD8a4Y10oBZ12NFIt-D0H9g,4834
85
- braintrust/prompt_cache/test_disk_cache.py,sha256=TSlkgQZT1yjM960eAn4kc8GntWfLf55HU3cdabGgI6M,7520
85
+ braintrust/prompt_cache/test_disk_cache.py,sha256=szmHQnIa5Rn2CouP9t5CmI6-D48BiX3Dktm6X2WRuWY,7522
86
86
  braintrust/prompt_cache/test_lru_cache.py,sha256=4NNIXSfYBtOma7KYum74UdeM83eYmcXSOeiNpuKYpwI,2342
87
87
  braintrust/prompt_cache/test_prompt_cache.py,sha256=x17Ru9eaix8jt6yMhRgEljD2vVe7ieA8uKhk3bszgSM,8447
88
88
  braintrust/wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -90,19 +90,21 @@ braintrust/wrappers/_anthropic_utils.py,sha256=tOj_rv5NVRXpCij0F3NPxOZg0XGAAXo8Y
90
90
  braintrust/wrappers/anthropic.py,sha256=sh0UbSWDarU5glic4HIUXNZmMcfn3Odau2K8HzaOIWY,11785
91
91
  braintrust/wrappers/dspy.py,sha256=ckPcMHpbVZP6k4R60ZbgegWz82lsK3lu2u9nvN0EIss,13516
92
92
  braintrust/wrappers/langchain.py,sha256=0aY5LuVA7BPkgWA0N6CwPG9EaPqRmVVfEPaM1kN4XZY,5028
93
+ braintrust/wrappers/langsmith_wrapper.py,sha256=mWhBnY6KypOlSQw4NrCwzif0Oe6SHV6LYGGiwiz-EJQ,17956
93
94
  braintrust/wrappers/litellm.py,sha256=ZE63C8OE5Z0N3mArwOWZusDXBW1MElPOCjODOF-tmB0,26616
94
95
  braintrust/wrappers/openai.py,sha256=SZuT4ouJd8FRNXxy9zM_OGb2HNL9XGsFnwkHCk3LDAM,10563
95
96
  braintrust/wrappers/pydantic_ai.py,sha256=AgMZS4F7c5Um-P98p13A0uapMFGuYf5YyXuDw1nwPHs,48534
96
- braintrust/wrappers/test_agno.py,sha256=e-ss-Lr7HMiGvPzsSSTxMblXgzyrbNebrvM062-lVHY,3668
97
- braintrust/wrappers/test_anthropic.py,sha256=tSHAnroaLK1QYhLhhPFAxSDEJUybzffp2o4IptDZRAU,15554
98
- braintrust/wrappers/test_dspy.py,sha256=jE-k-joobVbGm8DAyp1eEkbPt_xBleZ10wkWJXLp0nI,1952
99
- braintrust/wrappers/test_google_genai.py,sha256=W4p3TIuJi2_xXqIVFtwQta7ai-WeoSwAd2y_tReC3Z4,19967
100
- braintrust/wrappers/test_litellm.py,sha256=miOeXEQm6g8ypvx8LpGlPrnXW-U51glOBP49mdwptc0,23777
101
- braintrust/wrappers/test_oai_attachments.py,sha256=9UXaXXXzZMLi_Q97QyV2uEtpuTy6BYL6I4olyFfEJ04,11273
102
- braintrust/wrappers/test_openai.py,sha256=UqKtoIlZlqiLC6x7Rbv9zROgDdE5zvXZObbFMKpmifw,60237
103
- braintrust/wrappers/test_openrouter.py,sha256=9wIYuwObFkADH8h5pzHFB4C9TcL_HTeq1KlODYhSMLs,3987
104
- braintrust/wrappers/test_pydantic_ai_integration.py,sha256=zvBqXd7ik-wZEKNMVB6pRTrGZ3XcTSEZ_FG4Ogho9mA,104304
105
- braintrust/wrappers/test_pydantic_ai_wrap_openai.py,sha256=cxj6uQaObhQ97-mEjN2OStpL4swlWhaln3n2zpIEA_I,5056
97
+ braintrust/wrappers/test_agno.py,sha256=IyxhKOy8kfMbLR_fA__MK7aDvmsJpV-oh-7eez9hrw8,3452
98
+ braintrust/wrappers/test_anthropic.py,sha256=DcLrYhFUhBFiYcP_Su3FcEW6-Ubt21JzjY8Hxwzpcbw,15495
99
+ braintrust/wrappers/test_dspy.py,sha256=peWwbBBi8mpDhp2brs4ozd5cWz_CjYoyQTp7hjvt97U,1759
100
+ braintrust/wrappers/test_google_genai.py,sha256=dY5ZXeTscvrz_8HfSbMr2Qbb_0W-FzUvQSzpG6EZXnU,20204
101
+ braintrust/wrappers/test_langsmith_wrapper.py,sha256=wEbPNy4o7VVvcuHcsCJ-sy2EATvBxhUXTYFBQNkKCjs,10449
102
+ braintrust/wrappers/test_litellm.py,sha256=BAdksj_yzoY0LoHpnDHVgUpOaSxkI_I9Nk5ZZEVuaAU,23604
103
+ braintrust/wrappers/test_oai_attachments.py,sha256=_EtNXjQxPgqXmj6UYMZn9GF4GDZf8m_1_TrwiEk7HWQ,11100
104
+ braintrust/wrappers/test_openai.py,sha256=8gQqJigWmEe3_Nxc5vvPndLIuhIeBY2B2oHLU_vuUkk,60065
105
+ braintrust/wrappers/test_openrouter.py,sha256=8HUfILPugOMqcvttpq76KQrynFb0xZpazvta7TTSF6A,3849
106
+ braintrust/wrappers/test_pydantic_ai_integration.py,sha256=oK26oEI56feg3SwbA-fxkGtVMS8eAC9j-gJsOUudmzw,104106
107
+ braintrust/wrappers/test_pydantic_ai_wrap_openai.py,sha256=OO5NrbothkMr4v2sZ-EZLH7-yLj3k6TfdLG4uzXAsQk,5090
106
108
  braintrust/wrappers/test_utils.py,sha256=Qz7LYG5V0DK2KuTJ_YLGpO_Zr_LJFfJgZX_Ps8tlM_c,505
107
109
  braintrust/wrappers/agno/__init__.py,sha256=0ehV_7L_ILsMfZ1bKHnzcR_CvFM98KMbGFN9UiE94vI,2379
108
110
  braintrust/wrappers/agno/agent.py,sha256=m3HCxQNotJviJswGYMxxsOnMilF-DNGqeFZFJa2Zhs4,6473
@@ -114,8 +116,8 @@ braintrust/wrappers/claude_agent_sdk/__init__.py,sha256=dcBP61ijW2B4g902-09ZfIOk
114
116
  braintrust/wrappers/claude_agent_sdk/_wrapper.py,sha256=K6iWfnYSgRq0ETGQ7CCh4rF4JJ0CR-G-VkCUfeKEQ-c,15645
115
117
  braintrust/wrappers/claude_agent_sdk/test_wrapper.py,sha256=0NmohdECudFvWtc-5PbANtTXzexkkwIJhGbujydDrT8,6826
116
118
  braintrust/wrappers/google_genai/__init__.py,sha256=Yv4hBOUc6TjUpYH3bEW8UaYiZ-sm3TpdVfqUw50NwQU,15826
117
- braintrust-0.4.2.dist-info/METADATA,sha256=DiX2q-5LiIz53SvCzzwGvoISnjY7YK-peu5Sd6EVM6s,3753
118
- braintrust-0.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
119
- braintrust-0.4.2.dist-info/entry_points.txt,sha256=Zpc0_09g5xm8as5jHqqFq7fhwO0xHSNct_TrEMONS7Q,60
120
- braintrust-0.4.2.dist-info/top_level.txt,sha256=hw1-y-UFMf60RzAr8x_eM7SThbIuWfQsQIbVvqSF83A,11
121
- braintrust-0.4.2.dist-info/RECORD,,
119
+ braintrust-0.4.3.dist-info/METADATA,sha256=XPLnFVJXuBT2YvH3tVwcTR1L8M8gMSCvtpsHWH8AA30,3753
120
+ braintrust-0.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
121
+ braintrust-0.4.3.dist-info/entry_points.txt,sha256=Zpc0_09g5xm8as5jHqqFq7fhwO0xHSNct_TrEMONS7Q,60
122
+ braintrust-0.4.3.dist-info/top_level.txt,sha256=hw1-y-UFMf60RzAr8x_eM7SThbIuWfQsQIbVvqSF83A,11
123
+ braintrust-0.4.3.dist-info/RECORD,,