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.
- braintrust/_generated_types.py +224 -122
- braintrust/cli/install/api.py +1 -1
- braintrust/conftest.py +24 -0
- braintrust/devserver/test_server_integration.py +0 -11
- braintrust/functions/invoke.py +1 -8
- braintrust/generated_types.py +7 -7
- braintrust/logger.py +30 -35
- braintrust/prompt_cache/test_disk_cache.py +3 -3
- braintrust/span_types.py +3 -0
- braintrust/test_bt_json.py +23 -19
- braintrust/version.py +2 -2
- braintrust/wrappers/langsmith_wrapper.py +517 -0
- braintrust/wrappers/test_agno.py +0 -12
- braintrust/wrappers/test_anthropic.py +1 -11
- braintrust/wrappers/test_dspy.py +0 -11
- braintrust/wrappers/test_google_genai.py +6 -1
- braintrust/wrappers/test_langsmith_wrapper.py +338 -0
- braintrust/wrappers/test_litellm.py +0 -10
- braintrust/wrappers/test_oai_attachments.py +0 -10
- braintrust/wrappers/test_openai.py +3 -12
- braintrust/wrappers/test_openrouter.py +0 -9
- braintrust/wrappers/test_pydantic_ai_integration.py +0 -11
- braintrust/wrappers/test_pydantic_ai_wrap_openai.py +2 -0
- {braintrust-0.4.2.dist-info → braintrust-0.4.3.dist-info}/METADATA +1 -1
- {braintrust-0.4.2.dist-info → braintrust-0.4.3.dist-info}/RECORD +28 -26
- {braintrust-0.4.2.dist-info → braintrust-0.4.3.dist-info}/WHEEL +0 -0
- {braintrust-0.4.2.dist-info → braintrust-0.4.3.dist-info}/entry_points.txt +0 -0
- {braintrust-0.4.2.dist-info → braintrust-0.4.3.dist-info}/top_level.txt +0 -0
braintrust/generated_types.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Auto-generated file (internal git SHA
|
|
1
|
+
"""Auto-generated file (internal git SHA 87ac73f4945a47eff2d4e42775ba4dbc58854c73) -- do not modify"""
|
|
2
2
|
|
|
3
3
|
from ._generated_types import (
|
|
4
4
|
Acl,
|
|
@@ -10,6 +10,7 @@ from ._generated_types import (
|
|
|
10
10
|
AsyncScoringState,
|
|
11
11
|
AttachmentReference,
|
|
12
12
|
AttachmentStatus,
|
|
13
|
+
BatchedFacetData,
|
|
13
14
|
BraintrustAttachmentReference,
|
|
14
15
|
BraintrustModelParams,
|
|
15
16
|
CallEvent,
|
|
@@ -47,15 +48,13 @@ from ._generated_types import (
|
|
|
47
48
|
GraphEdge,
|
|
48
49
|
GraphNode,
|
|
49
50
|
Group,
|
|
51
|
+
GroupScope,
|
|
50
52
|
IfExists,
|
|
51
|
-
InvokeContext,
|
|
52
53
|
InvokeFunction,
|
|
53
54
|
InvokeParent,
|
|
54
|
-
InvokeScope,
|
|
55
55
|
MCPServer,
|
|
56
56
|
MessageRole,
|
|
57
57
|
ModelParams,
|
|
58
|
-
NullableFunctionTypeEnum,
|
|
59
58
|
NullableSavedFunctionId,
|
|
60
59
|
ObjectReference,
|
|
61
60
|
ObjectReferenceNullish,
|
|
@@ -99,6 +98,7 @@ from ._generated_types import (
|
|
|
99
98
|
StreamingMode,
|
|
100
99
|
ToolFunctionDefinition,
|
|
101
100
|
TraceScope,
|
|
101
|
+
TriggeredFunctionState,
|
|
102
102
|
UploadStatus,
|
|
103
103
|
User,
|
|
104
104
|
View,
|
|
@@ -117,6 +117,7 @@ __all__ = [
|
|
|
117
117
|
"AsyncScoringState",
|
|
118
118
|
"AttachmentReference",
|
|
119
119
|
"AttachmentStatus",
|
|
120
|
+
"BatchedFacetData",
|
|
120
121
|
"BraintrustAttachmentReference",
|
|
121
122
|
"BraintrustModelParams",
|
|
122
123
|
"CallEvent",
|
|
@@ -154,15 +155,13 @@ __all__ = [
|
|
|
154
155
|
"GraphEdge",
|
|
155
156
|
"GraphNode",
|
|
156
157
|
"Group",
|
|
158
|
+
"GroupScope",
|
|
157
159
|
"IfExists",
|
|
158
|
-
"InvokeContext",
|
|
159
160
|
"InvokeFunction",
|
|
160
161
|
"InvokeParent",
|
|
161
|
-
"InvokeScope",
|
|
162
162
|
"MCPServer",
|
|
163
163
|
"MessageRole",
|
|
164
164
|
"ModelParams",
|
|
165
|
-
"NullableFunctionTypeEnum",
|
|
166
165
|
"NullableSavedFunctionId",
|
|
167
166
|
"ObjectReference",
|
|
168
167
|
"ObjectReferenceNullish",
|
|
@@ -206,6 +205,7 @@ __all__ = [
|
|
|
206
205
|
"StreamingMode",
|
|
207
206
|
"ToolFunctionDefinition",
|
|
208
207
|
"TraceScope",
|
|
208
|
+
"TriggeredFunctionState",
|
|
209
209
|
"UploadStatus",
|
|
210
210
|
"User",
|
|
211
211
|
"View",
|
braintrust/logger.py
CHANGED
|
@@ -454,24 +454,22 @@ class BraintrustState:
|
|
|
454
454
|
|
|
455
455
|
def copy_state(self, other: "BraintrustState"):
|
|
456
456
|
"""Copy login information from another BraintrustState instance."""
|
|
457
|
-
self.__dict__.update(
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
)
|
|
457
|
+
self.__dict__.update({
|
|
458
|
+
k: v
|
|
459
|
+
for (k, v) in other.__dict__.items()
|
|
460
|
+
if k
|
|
461
|
+
not in (
|
|
462
|
+
"current_experiment",
|
|
463
|
+
"current_logger",
|
|
464
|
+
"current_parent",
|
|
465
|
+
"current_span",
|
|
466
|
+
"_global_bg_logger",
|
|
467
|
+
"_override_bg_logger",
|
|
468
|
+
"_context_manager",
|
|
469
|
+
"_last_otel_setting",
|
|
470
|
+
"_context_manager_lock",
|
|
471
|
+
)
|
|
472
|
+
})
|
|
475
473
|
|
|
476
474
|
def login(
|
|
477
475
|
self,
|
|
@@ -2344,6 +2342,7 @@ def _validate_and_sanitize_experiment_log_partial_args(event: Mapping[str, Any])
|
|
|
2344
2342
|
SKIP_ASYNC_SCORING_FIELD,
|
|
2345
2343
|
"span_id",
|
|
2346
2344
|
"root_span_id",
|
|
2345
|
+
"_bt_internal_override_pagination_key",
|
|
2347
2346
|
}
|
|
2348
2347
|
if forbidden_keys:
|
|
2349
2348
|
raise ValueError(f"The following keys are not permitted: {forbidden_keys}")
|
|
@@ -4403,24 +4402,20 @@ def render_message(render: Callable[[str], str], message: PromptMessage):
|
|
|
4403
4402
|
if c["type"] == "text":
|
|
4404
4403
|
rendered_content.append({**c, "text": render(c["text"])})
|
|
4405
4404
|
elif c["type"] == "image_url":
|
|
4406
|
-
rendered_content.append(
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
}
|
|
4411
|
-
)
|
|
4405
|
+
rendered_content.append({
|
|
4406
|
+
**c,
|
|
4407
|
+
"image_url": {**c["image_url"], "url": render(c["image_url"]["url"])},
|
|
4408
|
+
})
|
|
4412
4409
|
elif c["type"] == "file":
|
|
4413
|
-
rendered_content.append(
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
"file"
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
}
|
|
4423
|
-
)
|
|
4410
|
+
rendered_content.append({
|
|
4411
|
+
**c,
|
|
4412
|
+
"file": {
|
|
4413
|
+
**c["file"],
|
|
4414
|
+
"file_data": render(c["file"]["file_data"]),
|
|
4415
|
+
**({} if "file_id" not in c["file"] else {"file_id": render(c["file"]["file_id"])}),
|
|
4416
|
+
**({} if "filename" not in c["file"] else {"filename": render(c["file"]["filename"])}),
|
|
4417
|
+
},
|
|
4418
|
+
})
|
|
4424
4419
|
else:
|
|
4425
4420
|
raise ValueError(f"Unknown content type: {c['type']}")
|
|
4426
4421
|
|
|
@@ -39,7 +39,7 @@ class TestDiskCache(unittest.TestCase):
|
|
|
39
39
|
"a\nb",
|
|
40
40
|
]
|
|
41
41
|
for k in weird_keys:
|
|
42
|
-
time.sleep(0.
|
|
42
|
+
time.sleep(0.01) # make sure the mtimes are different
|
|
43
43
|
self.cache.set(k, data)
|
|
44
44
|
result = self.cache.get(k)
|
|
45
45
|
assert data == result
|
|
@@ -61,7 +61,7 @@ class TestDiskCache(unittest.TestCase):
|
|
|
61
61
|
# Fill cache beyond max size (3).
|
|
62
62
|
for i in range(3):
|
|
63
63
|
self.cache.set(f"key{i}", {"value": i})
|
|
64
|
-
time.sleep(0.
|
|
64
|
+
time.sleep(0.01) # wait to ensure different mtimes
|
|
65
65
|
|
|
66
66
|
# Add one more to trigger eviction.
|
|
67
67
|
self.cache.set("key3", {"value": 3})
|
|
@@ -75,7 +75,7 @@ class TestDiskCache(unittest.TestCase):
|
|
|
75
75
|
# Fill cache beyond max size (3).
|
|
76
76
|
for i in range(3):
|
|
77
77
|
self.cache.set(f"key{i}", {"value": i})
|
|
78
|
-
time.sleep(0.
|
|
78
|
+
time.sleep(0.01) # wait to ensure different mtimes
|
|
79
79
|
|
|
80
80
|
# Add one more to trigger eviction.
|
|
81
81
|
self.cache.set("key3", {"value": 3})
|
braintrust/span_types.py
CHANGED
braintrust/test_bt_json.py
CHANGED
|
@@ -5,6 +5,7 @@ import json
|
|
|
5
5
|
from typing import Any
|
|
6
6
|
from unittest import TestCase
|
|
7
7
|
|
|
8
|
+
import pytest
|
|
8
9
|
from braintrust.bt_json import bt_dumps, bt_safe_deep_copy
|
|
9
10
|
from braintrust.logger import Attachment, ExternalAttachment
|
|
10
11
|
|
|
@@ -281,30 +282,33 @@ class TestBTJson(TestCase):
|
|
|
281
282
|
self.assertTrue("(1, 2)" in result or "1, 2" in result)
|
|
282
283
|
self.assertIn("None", result)
|
|
283
284
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
@pytest.mark.vcr
|
|
286
|
+
def test_to_bt_safe_special_objects():
|
|
287
|
+
"""Test _to_bt_safe handling of Span, Experiment, Dataset, Logger objects."""
|
|
288
|
+
from braintrust import init, init_dataset, init_logger
|
|
287
289
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
290
|
+
# Create actual objects
|
|
291
|
+
exp = init(project="test", experiment="test")
|
|
292
|
+
dataset = init_dataset(project="test", name="test")
|
|
293
|
+
logger = init_logger(project="test")
|
|
294
|
+
span = exp.start_span()
|
|
293
295
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
+
# Import _to_bt_safe
|
|
297
|
+
from braintrust.bt_json import _to_bt_safe
|
|
298
|
+
|
|
299
|
+
# Test each special object
|
|
300
|
+
assert _to_bt_safe(span) == "<span>"
|
|
301
|
+
assert _to_bt_safe(exp) == "<experiment>"
|
|
302
|
+
assert _to_bt_safe(dataset) == "<dataset>"
|
|
303
|
+
assert _to_bt_safe(logger) == "<logger>"
|
|
296
304
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
self.assertEqual(_to_bt_safe(logger), "<logger>")
|
|
305
|
+
# Clean up
|
|
306
|
+
exp.flush()
|
|
307
|
+
dataset.flush()
|
|
308
|
+
logger.flush()
|
|
302
309
|
|
|
303
|
-
# Clean up
|
|
304
|
-
exp.flush()
|
|
305
|
-
dataset.flush()
|
|
306
|
-
logger.flush()
|
|
307
310
|
|
|
311
|
+
class TestBTJsonAttachments(TestCase):
|
|
308
312
|
def test_to_bt_safe_attachments(self):
|
|
309
313
|
"""Test _to_bt_safe preserves BaseAttachment and converts ReadonlyAttachment to reference."""
|
|
310
314
|
from braintrust.bt_json import _to_bt_safe
|
braintrust/version.py
CHANGED