braintrust 0.3.10__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.10 → braintrust-0.3.12}/PKG-INFO +1 -1
  2. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/auth.py +3 -0
  3. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/cors.py +1 -0
  4. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/server.py +6 -3
  5. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/test_server_integration.py +4 -5
  6. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/oai.py +1 -1
  7. braintrust-0.3.12/src/braintrust/version.py +4 -0
  8. braintrust-0.3.12/src/braintrust/wrappers/test_openrouter.py +144 -0
  9. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust.egg-info/PKG-INFO +1 -1
  10. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust.egg-info/SOURCES.txt +1 -0
  11. braintrust-0.3.10/src/braintrust/version.py +0 -4
  12. {braintrust-0.3.10 → braintrust-0.3.12}/README.md +0 -0
  13. {braintrust-0.3.10 → braintrust-0.3.12}/setup.cfg +0 -0
  14. {braintrust-0.3.10 → braintrust-0.3.12}/setup.py +0 -0
  15. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/__init__.py +0 -0
  16. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/_generated_types.py +0 -0
  17. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/audit.py +0 -0
  18. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/aws.py +0 -0
  19. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/bt_json.py +0 -0
  20. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/__init__.py +0 -0
  21. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/__main__.py +0 -0
  22. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/eval.py +0 -0
  23. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/install/__init__.py +0 -0
  24. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/install/api.py +0 -0
  25. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/install/bump_versions.py +0 -0
  26. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/install/logs.py +0 -0
  27. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/install/redshift.py +0 -0
  28. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/install/run_migrations.py +0 -0
  29. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/cli/push.py +0 -0
  30. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/conftest.py +0 -0
  31. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/context.py +0 -0
  32. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/contrib/__init__.py +0 -0
  33. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/contrib/temporal/__init__.py +0 -0
  34. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/contrib/temporal/test_temporal.py +0 -0
  35. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/db_fields.py +0 -0
  36. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/__init__.py +0 -0
  37. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/cache.py +0 -0
  38. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/dataset.py +0 -0
  39. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/eval_hooks.py +0 -0
  40. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/schemas.py +0 -0
  41. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/test_cached_login.py +0 -0
  42. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/devserver/test_lru_cache.py +0 -0
  43. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/framework.py +0 -0
  44. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/framework2.py +0 -0
  45. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/functions/__init__.py +0 -0
  46. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/functions/constants.py +0 -0
  47. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/functions/invoke.py +0 -0
  48. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/functions/stream.py +0 -0
  49. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/generated_types.py +0 -0
  50. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/git_fields.py +0 -0
  51. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/gitutil.py +0 -0
  52. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/graph_util.py +0 -0
  53. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/http_headers.py +0 -0
  54. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/id_gen.py +0 -0
  55. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/logger.py +0 -0
  56. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/merge_row_batch.py +0 -0
  57. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/object.py +0 -0
  58. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/otel/__init__.py +0 -0
  59. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/otel/context.py +0 -0
  60. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/otel/test_distributed_tracing.py +0 -0
  61. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/otel/test_otel_bt_integration.py +0 -0
  62. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/parameters.py +0 -0
  63. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/prompt.py +0 -0
  64. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/prompt_cache/__init__.py +0 -0
  65. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/prompt_cache/disk_cache.py +0 -0
  66. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/prompt_cache/lru_cache.py +0 -0
  67. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/prompt_cache/prompt_cache.py +0 -0
  68. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/prompt_cache/test_disk_cache.py +0 -0
  69. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/prompt_cache/test_lru_cache.py +0 -0
  70. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/prompt_cache/test_prompt_cache.py +0 -0
  71. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/py.typed +0 -0
  72. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/queue.py +0 -0
  73. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/resource_manager.py +0 -0
  74. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/score.py +0 -0
  75. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/serializable_data_class.py +0 -0
  76. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/span_identifier_v1.py +0 -0
  77. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/span_identifier_v2.py +0 -0
  78. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/span_identifier_v3.py +0 -0
  79. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/span_identifier_v4.py +0 -0
  80. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/span_types.py +0 -0
  81. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_framework.py +0 -0
  82. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_framework2.py +0 -0
  83. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_helpers.py +0 -0
  84. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_id_gen.py +0 -0
  85. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_logger.py +0 -0
  86. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_otel.py +0 -0
  87. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_queue.py +0 -0
  88. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_serializable_data_class.py +0 -0
  89. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_span_components.py +0 -0
  90. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_util.py +0 -0
  91. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/test_version.py +0 -0
  92. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/util.py +0 -0
  93. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/__init__.py +0 -0
  94. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/_anthropic_utils.py +0 -0
  95. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/agno/__init__.py +0 -0
  96. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/agno/agent.py +0 -0
  97. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/agno/function_call.py +0 -0
  98. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/agno/model.py +0 -0
  99. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/agno/team.py +0 -0
  100. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/agno/utils.py +0 -0
  101. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/anthropic.py +0 -0
  102. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/claude_agent_sdk/__init__.py +0 -0
  103. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/claude_agent_sdk/_wrapper.py +0 -0
  104. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/claude_agent_sdk/test_wrapper.py +0 -0
  105. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/dspy.py +0 -0
  106. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/google_genai/__init__.py +0 -0
  107. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/langchain.py +0 -0
  108. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/litellm.py +0 -0
  109. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/openai.py +0 -0
  110. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/test_agno.py +0 -0
  111. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/test_anthropic.py +0 -0
  112. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/test_dspy.py +0 -0
  113. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/test_google_genai.py +0 -0
  114. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/test_litellm.py +0 -0
  115. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/test_openai.py +0 -0
  116. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/test_pydantic_ai.py +0 -0
  117. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/wrappers/test_utils.py +0 -0
  118. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust/xact_ids.py +0 -0
  119. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust.egg-info/dependency_links.txt +0 -0
  120. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust.egg-info/entry_points.txt +0 -0
  121. {braintrust-0.3.10 → braintrust-0.3.12}/src/braintrust.egg-info/requires.txt +0 -0
  122. {braintrust-0.3.10 → 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.10
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
@@ -4,7 +4,6 @@ from pathlib import Path
4
4
  from typing import Any
5
5
 
6
6
  import pytest
7
-
8
7
  from braintrust.framework import _evals
9
8
  from braintrust.test_helpers import has_devserver_installed
10
9
 
@@ -28,9 +27,8 @@ def client():
28
27
  pytest.skip("Devserver dependencies not installed (requires .[cli])")
29
28
 
30
29
  # Import CLI dependencies inside the fixture
31
- from starlette.testclient import TestClient
32
-
33
30
  from braintrust.devserver.server import create_app
31
+ from starlette.testclient import TestClient
34
32
 
35
33
  # Use the real simple_eval.py example
36
34
  eval_file = Path(__file__).parent.parent.parent.parent / "examples" / "evals" / "simple_eval.py"
@@ -39,8 +37,8 @@ def client():
39
37
  _evals.clear()
40
38
 
41
39
  # Load the eval file to register evaluators (but don't run them)
42
- spec = __import__('importlib.util').util.spec_from_file_location("simple_eval", str(eval_file))
43
- module = __import__('importlib.util').util.module_from_spec(spec)
40
+ spec = __import__("importlib.util").util.spec_from_file_location("simple_eval", str(eval_file))
41
+ module = __import__("importlib.util").util.module_from_spec(spec)
44
42
 
45
43
  # Get evaluators from the module without executing Eval()
46
44
  # We need to parse the file and extract the Evaluator definition
@@ -134,6 +132,7 @@ def parse_sse_events(response_text: str) -> list[dict[str, Any]]:
134
132
  return events
135
133
 
136
134
 
135
+ @pytest.mark.skip
137
136
  @pytest.mark.vcr
138
137
  def test_eval_sse_streaming(client, api_key, org_name):
139
138
  """
@@ -845,7 +845,7 @@ def _parse_metrics_from_usage(usage: Any) -> Dict[str, Any]:
845
845
 
846
846
 
847
847
  def _is_numeric(v):
848
- return isinstance(v, (int, float, complex))
848
+ return isinstance(v, (int, float, complex)) and not isinstance(v, bool)
849
849
 
850
850
 
851
851
  def prettify_params(params: Dict[str, Any]) -> Dict[str, Any]:
@@ -0,0 +1,4 @@
1
+ VERSION = "0.3.12"
2
+
3
+ # this will be templated during the build
4
+ GIT_COMMIT = "8c2b2995c2097f5699c101f4ab5e653ff40014a1"
@@ -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.10
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.10"
2
-
3
- # this will be templated during the build
4
- GIT_COMMIT = "160c352d87c121ef1ea43e49831453b9e8d4d0f8"
File without changes
File without changes
File without changes