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.
@@ -1,4 +1,4 @@
1
- """Auto-generated file (internal git SHA 547fa17c0937e0e25fdf9214487be6f31c91a37a) -- do not modify"""
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
- k: v
460
- for (k, v) in other.__dict__.items()
461
- if k
462
- not in (
463
- "current_experiment",
464
- "current_logger",
465
- "current_parent",
466
- "current_span",
467
- "_global_bg_logger",
468
- "_override_bg_logger",
469
- "_context_manager",
470
- "_last_otel_setting",
471
- "_context_manager_lock",
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
- **c,
4409
- "image_url": {**c["image_url"], "url": render(c["image_url"]["url"])},
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
- **c,
4416
- "file": {
4417
- **c["file"],
4418
- "file_data": render(c["file"]["file_data"]),
4419
- **({} if "file_id" not in c["file"] else {"file_id": render(c["file"]["file_id"])}),
4420
- **({} if "filename" not in c["file"] else {"filename": render(c["file"]["filename"])}),
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.05) # make sure the mtimes are different
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.1) # wait to ensure different mtimes
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.1) # wait to ensure different mtimes
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
@@ -13,6 +13,9 @@ class SpanTypeAttribute(str, Enum):
13
13
  EVAL = "eval"
14
14
  TASK = "task"
15
15
  TOOL = "tool"
16
+ AUTOMATION = "automation"
17
+ FACET = "facet"
18
+ PREPROCESSOR = "preprocessor"
16
19
 
17
20
 
18
21
  class SpanPurpose(str, Enum):
@@ -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
- def test_to_bt_safe_special_objects(self):
285
- """Test _to_bt_safe handling of Span, Experiment, Dataset, Logger objects."""
286
- from braintrust import init, init_dataset, init_logger
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
- # Create actual objects
289
- exp = init(project="test", experiment="test")
290
- dataset = init_dataset(project="test", name="test")
291
- logger = init_logger(project="test")
292
- span = exp.start_span()
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
- # Import _to_bt_safe
295
- from braintrust.bt_json import _to_bt_safe
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
- # Test each special object
298
- self.assertEqual(_to_bt_safe(span), "<span>")
299
- self.assertEqual(_to_bt_safe(exp), "<experiment>")
300
- self.assertEqual(_to_bt_safe(dataset), "<dataset>")
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
@@ -1,4 +1,4 @@
1
- VERSION = "0.4.2"
1
+ VERSION = "0.4.3"
2
2
 
3
3
  # this will be templated during the build
4
- GIT_COMMIT = "3ca420e53e77d4665b91ccc7631c95dc97ce566d"
4
+ GIT_COMMIT = "d734e8ffc272ee65fe0588df00fd9390614ccd2e"