braintrust 0.3.11__tar.gz → 0.3.12__tar.gz

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 (122) hide show
  1. {braintrust-0.3.11 → braintrust-0.3.12}/PKG-INFO +1 -1
  2. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/auth.py +3 -0
  3. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/cors.py +1 -0
  4. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/server.py +6 -3
  5. braintrust-0.3.12/src/braintrust/version.py +4 -0
  6. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/test_openai.py +0 -32
  7. braintrust-0.3.12/src/braintrust/wrappers/test_openrouter.py +144 -0
  8. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust.egg-info/PKG-INFO +1 -1
  9. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust.egg-info/SOURCES.txt +1 -0
  10. braintrust-0.3.11/src/braintrust/version.py +0 -4
  11. {braintrust-0.3.11 → braintrust-0.3.12}/README.md +0 -0
  12. {braintrust-0.3.11 → braintrust-0.3.12}/setup.cfg +0 -0
  13. {braintrust-0.3.11 → braintrust-0.3.12}/setup.py +0 -0
  14. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/__init__.py +0 -0
  15. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/_generated_types.py +0 -0
  16. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/audit.py +0 -0
  17. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/aws.py +0 -0
  18. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/bt_json.py +0 -0
  19. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/__init__.py +0 -0
  20. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/__main__.py +0 -0
  21. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/eval.py +0 -0
  22. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/install/__init__.py +0 -0
  23. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/install/api.py +0 -0
  24. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/install/bump_versions.py +0 -0
  25. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/install/logs.py +0 -0
  26. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/install/redshift.py +0 -0
  27. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/install/run_migrations.py +0 -0
  28. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/cli/push.py +0 -0
  29. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/conftest.py +0 -0
  30. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/context.py +0 -0
  31. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/contrib/__init__.py +0 -0
  32. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/contrib/temporal/__init__.py +0 -0
  33. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/contrib/temporal/test_temporal.py +0 -0
  34. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/db_fields.py +0 -0
  35. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/__init__.py +0 -0
  36. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/cache.py +0 -0
  37. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/dataset.py +0 -0
  38. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/eval_hooks.py +0 -0
  39. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/schemas.py +0 -0
  40. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/test_cached_login.py +0 -0
  41. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/test_lru_cache.py +0 -0
  42. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/devserver/test_server_integration.py +0 -0
  43. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/framework.py +0 -0
  44. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/framework2.py +0 -0
  45. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/functions/__init__.py +0 -0
  46. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/functions/constants.py +0 -0
  47. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/functions/invoke.py +0 -0
  48. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/functions/stream.py +0 -0
  49. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/generated_types.py +0 -0
  50. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/git_fields.py +0 -0
  51. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/gitutil.py +0 -0
  52. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/graph_util.py +0 -0
  53. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/http_headers.py +0 -0
  54. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/id_gen.py +0 -0
  55. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/logger.py +0 -0
  56. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/merge_row_batch.py +0 -0
  57. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/oai.py +0 -0
  58. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/object.py +0 -0
  59. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/otel/__init__.py +0 -0
  60. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/otel/context.py +0 -0
  61. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/otel/test_distributed_tracing.py +0 -0
  62. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/otel/test_otel_bt_integration.py +0 -0
  63. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/parameters.py +0 -0
  64. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/prompt.py +0 -0
  65. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/prompt_cache/__init__.py +0 -0
  66. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/prompt_cache/disk_cache.py +0 -0
  67. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/prompt_cache/lru_cache.py +0 -0
  68. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/prompt_cache/prompt_cache.py +0 -0
  69. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/prompt_cache/test_disk_cache.py +0 -0
  70. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/prompt_cache/test_lru_cache.py +0 -0
  71. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/prompt_cache/test_prompt_cache.py +0 -0
  72. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/py.typed +0 -0
  73. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/queue.py +0 -0
  74. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/resource_manager.py +0 -0
  75. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/score.py +0 -0
  76. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/serializable_data_class.py +0 -0
  77. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/span_identifier_v1.py +0 -0
  78. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/span_identifier_v2.py +0 -0
  79. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/span_identifier_v3.py +0 -0
  80. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/span_identifier_v4.py +0 -0
  81. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/span_types.py +0 -0
  82. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_framework.py +0 -0
  83. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_framework2.py +0 -0
  84. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_helpers.py +0 -0
  85. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_id_gen.py +0 -0
  86. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_logger.py +0 -0
  87. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_otel.py +0 -0
  88. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_queue.py +0 -0
  89. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_serializable_data_class.py +0 -0
  90. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_span_components.py +0 -0
  91. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_util.py +0 -0
  92. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/test_version.py +0 -0
  93. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/util.py +0 -0
  94. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/__init__.py +0 -0
  95. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/_anthropic_utils.py +0 -0
  96. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/agno/__init__.py +0 -0
  97. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/agno/agent.py +0 -0
  98. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/agno/function_call.py +0 -0
  99. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/agno/model.py +0 -0
  100. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/agno/team.py +0 -0
  101. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/agno/utils.py +0 -0
  102. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/anthropic.py +0 -0
  103. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/claude_agent_sdk/__init__.py +0 -0
  104. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/claude_agent_sdk/_wrapper.py +0 -0
  105. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/claude_agent_sdk/test_wrapper.py +0 -0
  106. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/dspy.py +0 -0
  107. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/google_genai/__init__.py +0 -0
  108. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/langchain.py +0 -0
  109. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/litellm.py +0 -0
  110. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/openai.py +0 -0
  111. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/test_agno.py +0 -0
  112. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/test_anthropic.py +0 -0
  113. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/test_dspy.py +0 -0
  114. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/test_google_genai.py +0 -0
  115. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/test_litellm.py +0 -0
  116. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/test_pydantic_ai.py +0 -0
  117. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/wrappers/test_utils.py +0 -0
  118. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust/xact_ids.py +0 -0
  119. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust.egg-info/dependency_links.txt +0 -0
  120. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust.egg-info/entry_points.txt +0 -0
  121. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust.egg-info/requires.txt +0 -0
  122. {braintrust-0.3.11 → braintrust-0.3.12}/src/braintrust.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braintrust
3
- Version: 0.3.11
3
+ Version: 0.3.12
4
4
  Summary: SDK for integrating Braintrust
5
5
  Home-page: https://www.braintrust.dev
6
6
  Author: Braintrust
@@ -10,6 +10,7 @@ from ..logger import BraintrustState
10
10
  ORIGIN_HEADER = "origin"
11
11
  BRAINTRUST_AUTH_TOKEN_HEADER = "x-bt-auth-token"
12
12
  BRAINTRUST_ORG_NAME_HEADER = "x-bt-org-name"
13
+ BRAINTRUST_PROJECT_ID_HEADER = "x-bt-project-id"
13
14
 
14
15
 
15
16
  @dataclass
@@ -17,6 +18,7 @@ class RequestContext:
17
18
  app_origin: Optional[str]
18
19
  token: Optional[str]
19
20
  org_name: Optional[str]
21
+ project_id: Optional[str]
20
22
  state: Optional[BraintrustState]
21
23
 
22
24
 
@@ -56,6 +58,7 @@ class AuthorizationMiddleware(BaseHTTPMiddleware):
56
58
  app_origin=extract_allowed_origin(request.headers.get(ORIGIN_HEADER)),
57
59
  token=None,
58
60
  org_name=request.headers.get(BRAINTRUST_ORG_NAME_HEADER),
61
+ project_id=request.headers.get(BRAINTRUST_PROJECT_ID_HEADER),
59
62
  state=None,
60
63
  )
61
64
 
@@ -18,6 +18,7 @@ ALLOWED_HEADERS = [
18
18
  "x-bt-auth-token",
19
19
  "x-bt-parent",
20
20
  "x-bt-org-name",
21
+ "x-bt-project-id",
21
22
  "x-bt-stream-fmt",
22
23
  "x-bt-use-cache",
23
24
  "x-stainless-os",
@@ -196,7 +196,7 @@ async def run_eval(request: Request) -> Union[JSONResponse, StreamingResponse]:
196
196
  "state": state,
197
197
  "scores": evaluator.scores
198
198
  + [
199
- make_scorer(state, score["name"], score["function_id"])
199
+ make_scorer(state, score["name"], score["function_id"], ctx.project_id)
200
200
  for score in eval_data.get("scores", [])
201
201
  ],
202
202
  "stream": stream_fn,
@@ -305,7 +305,7 @@ def snake_to_camel(snake_str: str) -> str:
305
305
  return components[0] + "".join(x.title() for x in components[1:]) if components else snake_str
306
306
 
307
307
 
308
- def make_scorer(state: BraintrustState, name: str, score: FunctionId) -> EvalScorer[Any, Any]:
308
+ def make_scorer(state: BraintrustState, name: str, score: FunctionId, project_id: Optional[str] = None) -> EvalScorer[Any, Any]:
309
309
  def scorer_fn(input, output, expected, metadata):
310
310
  request = {
311
311
  **score,
@@ -315,7 +315,10 @@ def make_scorer(state: BraintrustState, name: str, score: FunctionId) -> EvalSco
315
315
  "mode": "auto",
316
316
  "strict": True,
317
317
  }
318
- result = state.proxy_conn().post("function/invoke", json=request, headers={"Accept": "application/json"})
318
+ headers = {"Accept": "application/json"}
319
+ if project_id:
320
+ headers["x-bt-project-id"] = project_id
321
+ result = state.proxy_conn().post("function/invoke", json=request, headers=headers)
319
322
  result.raise_for_status()
320
323
  data = result.json()
321
324
  return data
@@ -0,0 +1,4 @@
1
+ VERSION = "0.3.12"
2
+
3
+ # this will be templated during the build
4
+ GIT_COMMIT = "8c2b2995c2097f5699c101f4ab5e653ff40014a1"
@@ -1690,35 +1690,3 @@ def test_braintrust_tracing_processor_trace_metadata_logging(memory_logger):
1690
1690
  spans = memory_logger.pop()
1691
1691
  root_span = spans[0]
1692
1692
  assert root_span["metadata"]["conversation_id"] == "test-12345", "Should log trace metadata"
1693
-
1694
-
1695
- def test_parse_metrics_excludes_booleans():
1696
- """Test that boolean fields in usage objects are excluded from metrics.
1697
-
1698
- Reproduces issue where OpenRouter returns is_byok (a boolean) in the usage
1699
- object, which caused API validation errors: "Expected number, received boolean".
1700
-
1701
- In Python, bool is a subclass of int, so isinstance(True, int) returns True.
1702
- The fix ensures _is_numeric explicitly excludes booleans.
1703
- """
1704
- from braintrust.oai import _parse_metrics_from_usage
1705
-
1706
- # Simulate OpenRouter's usage object with boolean field
1707
- usage = {
1708
- "completion_tokens": 11,
1709
- "prompt_tokens": 8,
1710
- "total_tokens": 19,
1711
- "cost": 0.000104,
1712
- "is_byok": False, # This boolean should be filtered out
1713
- }
1714
-
1715
- metrics = _parse_metrics_from_usage(usage)
1716
-
1717
- # Numeric fields should be included
1718
- assert metrics["completion_tokens"] == 11
1719
- assert metrics["prompt_tokens"] == 8
1720
- assert metrics["tokens"] == 19 # total_tokens gets renamed
1721
- assert metrics["cost"] == 0.000104
1722
-
1723
- # Boolean field should NOT be in metrics (this was the bug)
1724
- assert "is_byok" not in metrics
@@ -0,0 +1,144 @@
1
+ """
2
+ Tests to ensure wrap_openai works correctly with OpenRouter.
3
+
4
+ OpenRouter is a popular API gateway that provides access to multiple LLM providers
5
+ through an OpenAI-compatible interface. This test validates that our wrapper handles
6
+ OpenRouter-specific response fields correctly (e.g., boolean `is_byok` in usage).
7
+ """
8
+
9
+ import os
10
+ import time
11
+
12
+ import pytest
13
+ from braintrust import logger, wrap_openai
14
+ from braintrust.test_helpers import init_test_logger
15
+ from braintrust.wrappers.test_utils import assert_metrics_are_valid
16
+ from openai import AsyncOpenAI, OpenAI
17
+
18
+ PROJECT_NAME = "test-openrouter"
19
+ TEST_MODEL = "openai/gpt-4o-mini"
20
+
21
+
22
+ @pytest.fixture(scope="module")
23
+ def vcr_config():
24
+ return {
25
+ "filter_headers": [
26
+ "authorization",
27
+ ]
28
+ }
29
+
30
+
31
+ @pytest.fixture
32
+ def memory_logger():
33
+ init_test_logger(PROJECT_NAME)
34
+ with logger._internal_with_memory_background_logger() as bgl:
35
+ yield bgl
36
+
37
+
38
+ def _get_client():
39
+ return OpenAI(
40
+ base_url="https://openrouter.ai/api/v1",
41
+ api_key=os.environ.get("OPENROUTER_API_KEY"),
42
+ )
43
+
44
+
45
+ def _get_async_client():
46
+ return AsyncOpenAI(
47
+ base_url="https://openrouter.ai/api/v1",
48
+ api_key=os.environ.get("OPENROUTER_API_KEY"),
49
+ )
50
+
51
+
52
+ @pytest.mark.vcr
53
+ def test_openrouter_chat_completion_sync(memory_logger):
54
+ assert not memory_logger.pop()
55
+
56
+ client = wrap_openai(_get_client())
57
+
58
+ start = time.time()
59
+ response = client.chat.completions.create(
60
+ model=TEST_MODEL,
61
+ messages=[{"role": "user", "content": "What is 2+2? Reply with just the number."}],
62
+ max_tokens=10,
63
+ )
64
+ end = time.time()
65
+
66
+ assert response
67
+ assert response.choices[0].message.content
68
+ assert "4" in response.choices[0].message.content
69
+
70
+ spans = memory_logger.pop()
71
+ assert len(spans) == 1
72
+ span = spans[0]
73
+
74
+ metrics = span["metrics"]
75
+ assert_metrics_are_valid(metrics, start, end)
76
+
77
+ # Ensure no boolean values in metrics (the original bug with is_byok)
78
+ for key, value in metrics.items():
79
+ assert not isinstance(value, bool), f"Metric {key} should not be a boolean"
80
+
81
+
82
+ @pytest.mark.vcr
83
+ @pytest.mark.asyncio
84
+ async def test_openrouter_chat_completion_async(memory_logger):
85
+ """Test that wrap_openai works with OpenRouter's async client."""
86
+ assert not memory_logger.pop()
87
+
88
+ client = wrap_openai(_get_async_client())
89
+
90
+ start = time.time()
91
+ response = await client.chat.completions.create(
92
+ model=TEST_MODEL,
93
+ messages=[{"role": "user", "content": "What is 3+3? Reply with just the number."}],
94
+ max_tokens=10,
95
+ )
96
+ end = time.time()
97
+
98
+ assert response
99
+ assert response.choices[0].message.content
100
+ assert "6" in response.choices[0].message.content
101
+
102
+ spans = memory_logger.pop()
103
+ assert len(spans) == 1
104
+ span = spans[0]
105
+
106
+ metrics = span["metrics"]
107
+ assert_metrics_are_valid(metrics, start, end)
108
+
109
+ for key, value in metrics.items():
110
+ assert not isinstance(value, bool), f"Metric {key} should not be a boolean"
111
+
112
+
113
+ @pytest.mark.vcr
114
+ def test_openrouter_streaming_sync(memory_logger):
115
+ """Test that wrap_openai works with OpenRouter's streaming responses."""
116
+ assert not memory_logger.pop()
117
+
118
+ client = wrap_openai(_get_client())
119
+
120
+ start = time.time()
121
+ chunks = []
122
+ stream = client.chat.completions.create(
123
+ model=TEST_MODEL,
124
+ messages=[{"role": "user", "content": "What is 5+5? Reply with just the number."}],
125
+ max_tokens=10,
126
+ stream=True,
127
+ )
128
+ for chunk in stream:
129
+ chunks.append(chunk)
130
+ end = time.time()
131
+
132
+ assert chunks
133
+ content = "".join(c.choices[0].delta.content or "" for c in chunks if c.choices)
134
+ assert "10" in content
135
+
136
+ spans = memory_logger.pop()
137
+ assert len(spans) == 1
138
+ span = spans[0]
139
+
140
+ metrics = span["metrics"]
141
+ assert_metrics_are_valid(metrics, start, end)
142
+
143
+ for key, value in metrics.items():
144
+ assert not isinstance(value, bool), f"Metric {key} should not be a boolean"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: braintrust
3
- Version: 0.3.11
3
+ Version: 0.3.12
4
4
  Summary: SDK for integrating Braintrust
5
5
  Home-page: https://www.braintrust.dev
6
6
  Author: Braintrust
@@ -104,6 +104,7 @@ src/braintrust/wrappers/test_dspy.py
104
104
  src/braintrust/wrappers/test_google_genai.py
105
105
  src/braintrust/wrappers/test_litellm.py
106
106
  src/braintrust/wrappers/test_openai.py
107
+ src/braintrust/wrappers/test_openrouter.py
107
108
  src/braintrust/wrappers/test_pydantic_ai.py
108
109
  src/braintrust/wrappers/test_utils.py
109
110
  src/braintrust/wrappers/agno/__init__.py
@@ -1,4 +0,0 @@
1
- VERSION = "0.3.11"
2
-
3
- # this will be templated during the build
4
- GIT_COMMIT = "7cffe54f8b960931055ae20f5983b4ea34515eff"
File without changes
File without changes
File without changes