From 54f2b975b8c18f6ec662b57f008f3377e01b454a Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 6 Aug 2026 11:35:42 -0400 Subject: [PATCH 1/3] feat(cursor_sdk): instrument Cursor agent runs Add tracing for sync and async Cursor agents, model turns, tools, usage, errors, and multimodal attachments, with versioned VCR coverage. Automatic instrumentation is preferred and must run before importing `cursor_sdk`: ```python import braintrust braintrust.auto_instrument() braintrust.init_logger(project="my-project") ``` For manual setup: ```python from braintrust.integrations.cursor_sdk import setup_cursor_sdk setup_cursor_sdk(project="my-project") ``` Custom agent classes can also be instrumented directly: ```python from braintrust.integrations.cursor_sdk import wrap_cursor_sdk_agent wrap_cursor_sdk_agent(MyAgent) ``` Requires Python >=3.10 and cursor-sdk >=1.0.25. The test matrix covers the minimum 1.0.25 release and the latest pinned release, 1.0.26. --- README.md | 1 + examples/cursor_sdk/README.md | 15 + examples/cursor_sdk/example.py | 20 + examples/cursor_sdk/pyproject.toml | 12 + py/noxfile.py | 16 + py/pyproject.toml | 8 + py/src/braintrust/auto.py | 5 + py/src/braintrust/integrations/__init__.py | 2 + .../auto_test_scripts/test_auto_cursor_sdk.py | 43 ++ .../integrations/cursor_sdk/__init__.py | 40 ++ .../integrations/cursor_sdk/_test_vcr.py | 71 +++ .../1.0.25/test_agent_prompt_one_shot.yaml | 200 ++++++ ...nsumption_paths_finalize_once[events].yaml | 227 +++++++ ...mption_paths_finalize_once[iter_text].yaml | 227 +++++++ ...mption_paths_finalize_once[iteration].yaml | 227 +++++++ ...nsumption_paths_finalize_once[stream].yaml | 227 +++++++ ...consumption_paths_finalize_once[text].yaml | 227 +++++++ ...messages_preserve_callbacks_and_trace.yaml | 227 +++++++ .../1.0.25/test_auto_cursor_sdk.yaml | 200 ++++++ ...ltin_tool_events_create_one_tool_span.yaml | 236 +++++++ ...acterize_no_downstream_provider_spans.yaml | 197 ++++++ ..._dispatch_traces_under_the_agents_run.yaml | 306 +++++++++ ...timodal_input_materializes_attachment.yaml | 257 ++++++++ ...t_resume_send_observe_finalizes_trace.yaml | 413 ++++++++++++ ...rror_propagates_and_logs_parent_error.yaml | 190 ++++++ ...nsumption_paths_finalize_once[events].yaml | 200 ++++++ ...mption_paths_finalize_once[iter_text].yaml | 200 ++++++ ...mption_paths_finalize_once[iteration].yaml | 200 ++++++ ...umption_paths_finalize_once[messages].yaml | 200 ++++++ ...nsumption_paths_finalize_once[stream].yaml | 200 ++++++ ...consumption_paths_finalize_once[text].yaml | 200 ++++++ ...c_wait_traces_cursor_owned_model_turn.yaml | 200 ++++++ .../latest/test_agent_prompt_one_shot.yaml | 283 +++++++++ ...nsumption_paths_finalize_once[events].yaml | 227 +++++++ ...mption_paths_finalize_once[iter_text].yaml | 227 +++++++ ...mption_paths_finalize_once[iteration].yaml | 227 +++++++ ...nsumption_paths_finalize_once[stream].yaml | 227 +++++++ ...consumption_paths_finalize_once[text].yaml | 227 +++++++ ...messages_preserve_callbacks_and_trace.yaml | 227 +++++++ .../latest/test_auto_cursor_sdk.yaml | 283 +++++++++ ...ltin_tool_events_create_one_tool_span.yaml | 237 +++++++ ...acterize_no_downstream_provider_spans.yaml | 201 ++++++ ..._dispatch_traces_under_the_agents_run.yaml | 302 +++++++++ ...timodal_input_materializes_attachment.yaml | 271 ++++++++ ...t_resume_send_observe_finalizes_trace.yaml | 415 ++++++++++++ ...rror_propagates_and_logs_parent_error.yaml | 190 ++++++ ...nsumption_paths_finalize_once[events].yaml | 283 +++++++++ ...mption_paths_finalize_once[iter_text].yaml | 283 +++++++++ ...mption_paths_finalize_once[iteration].yaml | 283 +++++++++ ...umption_paths_finalize_once[messages].yaml | 283 +++++++++ ...nsumption_paths_finalize_once[stream].yaml | 283 +++++++++ ...consumption_paths_finalize_once[text].yaml | 283 +++++++++ ...c_wait_traces_cursor_owned_model_turn.yaml | 283 +++++++++ .../integrations/cursor_sdk/integration.py | 15 + .../integrations/cursor_sdk/patchers.py | 123 ++++ .../cursor_sdk/test_cursor_sdk.py | 483 ++++++++++++++ .../integrations/cursor_sdk/tracing.py | 598 ++++++++++++++++++ py/src/braintrust/integrations/test_utils.py | 6 +- 58 files changed, 11743 insertions(+), 1 deletion(-) create mode 100644 examples/cursor_sdk/README.md create mode 100644 examples/cursor_sdk/example.py create mode 100644 examples/cursor_sdk/pyproject.toml create mode 100644 py/src/braintrust/integrations/auto_test_scripts/test_auto_cursor_sdk.py create mode 100644 py/src/braintrust/integrations/cursor_sdk/__init__.py create mode 100644 py/src/braintrust/integrations/cursor_sdk/_test_vcr.py create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_agent_prompt_one_shot.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[events].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[iter_text].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[iteration].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[stream].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[text].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_messages_preserve_callbacks_and_trace.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_auto_cursor_sdk.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_builtin_tool_events_create_one_tool_span.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_characterize_no_downstream_provider_spans.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_custom_tool_dispatch_traces_under_the_agents_run.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_multimodal_input_materializes_attachment.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_resume_send_observe_finalizes_trace.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_send_error_propagates_and_logs_parent_error.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[events].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[iter_text].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[iteration].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[messages].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[stream].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[text].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_wait_traces_cursor_owned_model_turn.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_agent_prompt_one_shot.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[events].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[iter_text].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[iteration].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[stream].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[text].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_messages_preserve_callbacks_and_trace.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_auto_cursor_sdk.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_builtin_tool_events_create_one_tool_span.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_characterize_no_downstream_provider_spans.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_custom_tool_dispatch_traces_under_the_agents_run.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_multimodal_input_materializes_attachment.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_resume_send_observe_finalizes_trace.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_send_error_propagates_and_logs_parent_error.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[events].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[iter_text].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[iteration].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[messages].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[stream].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[text].yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_wait_traces_cursor_owned_model_turn.yaml create mode 100644 py/src/braintrust/integrations/cursor_sdk/integration.py create mode 100644 py/src/braintrust/integrations/cursor_sdk/patchers.py create mode 100644 py/src/braintrust/integrations/cursor_sdk/test_cursor_sdk.py create mode 100644 py/src/braintrust/integrations/cursor_sdk/tracing.py diff --git a/README.md b/README.md index 473b8b5c..300af9fe 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ BRAINTRUST_API_KEY= braintrust eval tutorial_eval.py | [DSPy](py/src/braintrust/integrations/dspy/) | Yes | `dspy>=2.6.0` | | [OpenAI Agents](py/src/braintrust/integrations/openai_agents/) | Yes | `openai-agents>=0.0.19` | | [Claude Agent SDK](py/src/braintrust/integrations/claude_agent_sdk/) | Yes | `claude_agent_sdk>=0.1.10` | +| [Cursor SDK](py/src/braintrust/integrations/cursor_sdk/) | Yes | `cursor-sdk>=1.0.25` | | [AutoGen](py/src/braintrust/integrations/autogen/) | Yes | `autogen-agentchat>=0.7.0` | | [CrewAI](py/src/braintrust/integrations/crewai/) | Yes | `crewai>=1.13.0` | | [Strands](py/src/braintrust/integrations/strands/) | Yes | `strands-agents>=1.20.0` | diff --git a/examples/cursor_sdk/README.md b/examples/cursor_sdk/README.md new file mode 100644 index 00000000..95f3f14c --- /dev/null +++ b/examples/cursor_sdk/README.md @@ -0,0 +1,15 @@ +# Cursor SDK + Braintrust + +Calls `braintrust.auto_instrument()` to wrap Cursor's `Agent`/`AsyncAgent` runs, then sends a single prompt. The trace shows a task span for the run, an LLM span per model turn, and a tool span for each tool the agent invokes. + +Cursor executes the model calls inside its own bridge subprocess, so the LLM span is reconstructed from the run's streamed events rather than from a provider client. + +## Run + +```bash +export BRAINTRUST_API_KEY=... +export CURSOR_API_KEY=... + +uv sync +uv run python example.py +``` diff --git a/examples/cursor_sdk/example.py b/examples/cursor_sdk/example.py new file mode 100644 index 00000000..18af6918 --- /dev/null +++ b/examples/cursor_sdk/example.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +"""Cursor SDK agent traced with Braintrust auto-instrumentation.""" + +import os + +import braintrust + + +braintrust.auto_instrument() +braintrust.init_logger(project="example-cursor-sdk") + +from cursor_sdk import Agent, LocalAgentOptions # pylint: disable=import-error,wrong-import-position + + +with Agent.create( + model="composer-2.5", + local=LocalAgentOptions(cwd=os.getcwd()), +) as agent: + result = agent.send("Summarize what this repository does").wait() + print(result.result) diff --git a/examples/cursor_sdk/pyproject.toml b/examples/cursor_sdk/pyproject.toml new file mode 100644 index 00000000..8400e774 --- /dev/null +++ b/examples/cursor_sdk/pyproject.toml @@ -0,0 +1,12 @@ +[project] +name = "braintrust-cursor-sdk-example" +version = "0.1.0" +description = "Cursor SDK traced with Braintrust" +requires-python = ">=3.10" +dependencies = [ + "braintrust", + "cursor-sdk", +] + +[tool.uv.sources] +braintrust = { path = "../../py", editable = true } diff --git a/py/noxfile.py b/py/noxfile.py index 60c44805..926c8e5f 100644 --- a/py/noxfile.py +++ b/py/noxfile.py @@ -351,6 +351,22 @@ def test_claude_agent_sdk(session, version): _run_tests(session, f"{INTEGRATION_DIR}/claude_agent_sdk/test_claude_agent_sdk.py", version=version) +CURSOR_SDK_VERSIONS = _get_matrix_versions("cursor-sdk") + + +@nox.session() +@nox.parametrize("version", CURSOR_SDK_VERSIONS, ids=CURSOR_SDK_VERSIONS) +def test_cursor_sdk(session, version): + _install_test_deps(session) + _install_matrix_dep(session, "cursor-sdk", version) + # Characterization coverage enables likely downstream provider + # instrumentation and verifies that Cursor's subprocess bridge does not + # emit provider-owned Python spans for its internal model requests. + _install_matrix_dep(session, "openai", LATEST) + _install_matrix_dep(session, "anthropic", LATEST) + _run_tests(session, f"{INTEGRATION_DIR}/cursor_sdk/test_cursor_sdk.py", version=version) + + # Pin 2.4.0 to cover the 2.4 -> 2.5 breaking change to internals we leverage for instrumentation. AGNO_VERSIONS = _get_matrix_versions("agno") diff --git a/py/pyproject.toml b/py/pyproject.toml index 0787f36a..62ae1e3d 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -377,6 +377,12 @@ latest = "pipecat-ai==1.4.0" latest = "claude-agent-sdk==0.2.129" "0.1.10" = "claude-agent-sdk==0.1.10" +[tool.braintrust.matrix.cursor-sdk] +# 1.0.25 fixes bridge callback tokens that could be parsed as CLI flags while +# retaining per-turn usage, sync/async consumption, multimodal, and custom tools. +latest = "cursor-sdk==1.0.26" +"1.0.25" = "cursor-sdk==1.0.25" + [tool.braintrust.matrix.agno] latest = "agno==2.8.6" "2.4.0" = "agno==2.4.0" @@ -511,6 +517,7 @@ anthropic = ["anthropic"] bedrock_runtime = ["boto3", "botocore"] cohere = ["cohere"] claude_agent_sdk = ["claude-agent-sdk"] +cursor_sdk = ["cursor-sdk"] crewai = ["crewai"] dspy = ["dspy"] google_genai = ["google-genai"] @@ -540,6 +547,7 @@ braintrust-core = "braintrust_core" boto3 = "boto3" botocore = "botocore" crewai = "crewai" +cursor-sdk = "cursor_sdk" dspy = "dspy" google-adk = "google.adk" google-genai = "google.genai" diff --git a/py/src/braintrust/auto.py b/py/src/braintrust/auto.py index b873fe6d..b43ce4bf 100644 --- a/py/src/braintrust/auto.py +++ b/py/src/braintrust/auto.py @@ -17,6 +17,7 @@ ClaudeAgentSDKIntegration, CohereIntegration, CrewAIIntegration, + CursorSDKIntegration, DSPyIntegration, GoogleGenAIIntegration, HuggingFaceHubIntegration, @@ -67,6 +68,7 @@ def auto_instrument( agno: bool = True, agentscope: bool = True, claude_agent_sdk: bool = True, + cursor_sdk: bool = True, dspy: bool = True, adk: bool = True, langchain: bool = True, @@ -103,6 +105,7 @@ def auto_instrument( agno: Enable Agno instrumentation (default: True) agentscope: Enable AgentScope instrumentation (default: True) claude_agent_sdk: Enable Claude Agent SDK instrumentation (default: True) + cursor_sdk: Enable Cursor SDK instrumentation (default: True) dspy: Enable DSPy instrumentation (default: True) adk: Enable Google ADK instrumentation (default: True) langchain: Enable LangChain instrumentation (default: True) @@ -187,6 +190,8 @@ def auto_instrument( results["agentscope"] = _instrument_integration(AgentScopeIntegration) if claude_agent_sdk: results["claude_agent_sdk"] = _instrument_integration(ClaudeAgentSDKIntegration) + if cursor_sdk: + results["cursor_sdk"] = _instrument_integration(CursorSDKIntegration) if dspy: results["dspy"] = _instrument_integration(DSPyIntegration) if adk: diff --git a/py/src/braintrust/integrations/__init__.py b/py/src/braintrust/integrations/__init__.py index c9b69d9a..795e9510 100644 --- a/py/src/braintrust/integrations/__init__.py +++ b/py/src/braintrust/integrations/__init__.py @@ -7,6 +7,7 @@ from .claude_agent_sdk import ClaudeAgentSDKIntegration from .cohere import CohereIntegration from .crewai import CrewAIIntegration +from .cursor_sdk import CursorSDKIntegration from .dspy import DSPyIntegration from .google_genai import GoogleGenAIIntegration from .huggingface_hub import HuggingFaceHubIntegration @@ -35,6 +36,7 @@ "ClaudeAgentSDKIntegration", "CohereIntegration", "CrewAIIntegration", + "CursorSDKIntegration", "DSPyIntegration", "GoogleGenAIIntegration", "HuggingFaceHubIntegration", diff --git a/py/src/braintrust/integrations/auto_test_scripts/test_auto_cursor_sdk.py b/py/src/braintrust/integrations/auto_test_scripts/test_auto_cursor_sdk.py new file mode 100644 index 00000000..0c05cef4 --- /dev/null +++ b/py/src/braintrust/integrations/auto_test_scripts/test_auto_cursor_sdk.py @@ -0,0 +1,43 @@ +"""Subprocess coverage for Cursor SDK auto-instrumentation and import order.""" + +# pylint: disable=import-error + +import os +import tempfile +from pathlib import Path + +import cursor_sdk +from braintrust.auto import auto_instrument +from braintrust.integrations.cursor_sdk._test_vcr import cursor_vcr_config +from braintrust.integrations.test_utils import autoinstrument_test_context +from braintrust.span_types import SpanTypeAttribute +from braintrust.test_helpers import find_spans_by_type + + +results = auto_instrument() +assert results.get("cursor_sdk") is True +assert auto_instrument().get("cursor_sdk") is True + + +with tempfile.TemporaryDirectory() as workspace: + Path(workspace, "README.md").write_text("Cursor auto-instrumentation workspace.\n", encoding="utf-8") + with autoinstrument_test_context( + "test_auto_cursor_sdk", + integration="cursor_sdk", + vcr_config=cursor_vcr_config(), + ) as memory_logger: + with cursor_sdk.CursorClient.launch_bridge(workspace=workspace) as client: + with client.agents.create( + model="composer-2.5", + api_key=os.environ.get("CURSOR_API_KEY", "crsr_test_key_for_cassette_playback"), + local=cursor_sdk.LocalAgentOptions(cwd=workspace), + ) as agent: + result = agent.send("Reply with exactly: cursor tracing complete").wait() + + assert result.status == "finished" + spans = memory_logger.pop() + assert find_spans_by_type(spans, SpanTypeAttribute.TASK) + assert find_spans_by_type(spans, SpanTypeAttribute.LLM) + assert all(span["context"]["span_origin"]["instrumentation"]["name"] == "cursor-sdk-auto" for span in spans) + +print("SUCCESS") diff --git a/py/src/braintrust/integrations/cursor_sdk/__init__.py b/py/src/braintrust/integrations/cursor_sdk/__init__.py new file mode 100644 index 00000000..2e29fd67 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/__init__.py @@ -0,0 +1,40 @@ +"""Braintrust tracing integration for the Cursor Python SDK.""" + +import inspect +from typing import Any + +from braintrust.logger import NOOP_SPAN, current_span, init_logger + +from .integration import CursorSDKIntegration +from .patchers import AgentClosePatcher, AgentSendPatcher, AsyncAgentClosePatcher, AsyncAgentSendPatcher + + +__all__ = ["CursorSDKIntegration", "setup_cursor_sdk", "wrap_cursor_sdk_agent"] + + +def setup_cursor_sdk( + api_key: str | None = None, + project_id: str | None = None, + project: str | None = None, +) -> bool: + """Patch Cursor SDK agent runs for Braintrust tracing.""" + if current_span() == NOOP_SPAN: + init_logger(project=project, api_key=api_key, project_id=project_id) + return CursorSDKIntegration.setup() + + +def wrap_cursor_sdk_agent(agent_class: Any) -> Any: + """Instrument a Cursor ``Agent`` or ``AsyncAgent`` class in place. + + Cursor traces model turns off ``Run``, not ``Agent``, so this also runs + the full integration setup to patch the run lifecycle. + """ + CursorSDKIntegration.setup() + # Both flavors spell these methods `send`/`close`, so the composite + # patcher cannot tell them apart when wrapping a class directly. + is_async = inspect.iscoroutinefunction(getattr(agent_class, "send", None)) + send_patcher = AsyncAgentSendPatcher if is_async else AgentSendPatcher + close_patcher = AsyncAgentClosePatcher if is_async else AgentClosePatcher + send_patcher.wrap_target(agent_class) + close_patcher.wrap_target(agent_class) + return agent_class diff --git a/py/src/braintrust/integrations/cursor_sdk/_test_vcr.py b/py/src/braintrust/integrations/cursor_sdk/_test_vcr.py new file mode 100644 index 00000000..b6d547b2 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/_test_vcr.py @@ -0,0 +1,71 @@ +"""Cursor bridge request scrubbing for pytest-vcr cassettes.""" + +import json +import re +import struct +from collections.abc import Mapping +from urllib.parse import urlsplit, urlunsplit + +from braintrust.conftest import get_vcr_config + + +# `cursor_sdk._tool_callback.TOOL_CALLBACK_SERVICE`, inlined so this module stays +# importable without the SDK installed. +_TOOL_CALLBACK_PATH_PREFIX = "/sdk.v1.SdkCustomToolCallbackService/" +_SENSITIVE_KEY_RE = re.compile(r"(?:api.?key|authorization|auth.?token|secret|password|env.?vars|headers)$", re.I) +_PATH_KEY_RE = re.compile(r"(?:cwd|workspace|state.?root)$", re.I) +_IDEMPOTENCY_KEY_RE = re.compile(r"idempotency.?key$", re.I) + + +def _scrub_value(value, *, key=""): + if key == "data" and isinstance(value, str) and len(value) >= 20: + return "" + if _SENSITIVE_KEY_RE.search(key): + return "" + if _PATH_KEY_RE.search(key): + return "" + if _IDEMPOTENCY_KEY_RE.search(key): + return "" + if isinstance(value, Mapping): + return {str(item_key): _scrub_value(item, key=str(item_key)) for item_key, item in value.items()} + if isinstance(value, list): + return [_scrub_value(item, key=key) for item in value] + return value + + +def scrub_cursor_bridge_request(request): + """Redact secrets/paths and normalize the bridge's dynamic loopback URL.""" + parts = urlsplit(request.uri) + # Let shutdown reach the real test bridge. Replaying this request would + # leave the bridge's child Node process running after the test exits. + if parts.path.endswith("/Shutdown"): + return None + # Custom tools arrive as a request *into* the SDK's loopback callback + # server, which VCR cannot record. Let the test drive that server for real + # instead of matching these against the cassette. + if parts.path.startswith(_TOOL_CALLBACK_PATH_PREFIX): + return None + request.uri = urlunsplit((parts.scheme, "cursor-sdk-bridge", parts.path, parts.query, parts.fragment)) + body = request.body + if not isinstance(body, bytes) or not body: + return request + is_connect_stream = request.headers.get("Content-Type") == "application/connect+json" + prefix = body[:5] if is_connect_stream else b"" + payload = body[5:] if is_connect_stream else body + try: + scrubbed = json.dumps(_scrub_value(json.loads(payload.decode("utf-8")))).encode("utf-8") + except (UnicodeDecodeError, json.JSONDecodeError): + return request + if is_connect_stream: + prefix = bytes([prefix[0]]) + struct.pack(">I", len(scrubbed)) + request.body = prefix + scrubbed + return request + + +def cursor_vcr_config(): + """Return standard VCR configuration specialized for Cursor bridge RPCs.""" + config = get_vcr_config() + config["before_record_request"] = scrub_cursor_bridge_request + config["filter_headers"] = [*config["filter_headers"], "host"] + config["match_on"] = ["method", "path", "body"] + return config diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_agent_prompt_one_shot.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_agent_prompt_one_shot.yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_agent_prompt_one_shot.yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[events].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[events].yaml new file mode 100644 index 00000000..8d4e4f48 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[events].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:31 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAACAeyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fX0AAAAA + 2nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlu + a2luZyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fSwib2Zmc2V0IjoiMyJ9AAAAAGR7Im9m + ZnNldCI6IjQiLCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRh + dGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo1fX19AAAAAHl7Im9mZnNldCI6IjUi + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ1cGRhdGUiOnsi + dHlwZSI6InRoaW5raW5nLWRlbHRhIiwidGV4dCI6IiB0ZXh0IHJlcXVlc3RlZC4ifX19AAAAANN7 + InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJhZ2VudF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJh + NyIsInJ1bl9pZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJ0 + ZXh0IjoiIHRleHQgcmVxdWVzdGVkLiJ9fSwib2Zmc2V0IjoiNiJ9AAAAAGR7Im9mZnNldCI6Ijci + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlw + ZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo0fX19AAAAAKZ7Im9mZnNldCI6IjgiLCJzdGVwIjp7 + InR5cGUiOiJ0aGlua2luZ01lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJ0aGlua2luZ01lc3NhZ2Ui + LCJtZXNzYWdlIjp7InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCB0ZXh0IHJlcXVlc3Rl + ZC4iLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH57Im9mZnNldCI6IjkiLCJpbnRlcmFj + dGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctY29tcGxldGVkIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1jb21wbGV0ZWQiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX0AAAAA3Xsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIs + ImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3Iiwi + cnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsInRleHQi + OiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6MX19LCJvZmZzZXQiOiIxMCJ9AAAAAGh7Im9mZnNl + dCI6IjExIiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUi + OnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0IjoiY3Vyc29yIn19fQAAAAEHeyJzZGtNZXNzYWdl + Ijp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2Vu + dF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bl9p + ZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJtZXNzYWdlIjp7 + InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJz + b3IifV19fX0sIm9mZnNldCI6IjEyIn0AAAAAZXsib2Zmc2V0IjoiMTMiLCJpbnRlcmFjdGlvblVw + ZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRh + IiwidG9rZW5zIjoyfX19AAAAAHl7Im9mZnNldCI6IjE0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsi + dHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0Ijoi + IGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19AAAAARh7InNka01lc3NhZ2UiOnsidHlwZSI6ImFz + c2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQt + MmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0 + Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lz + dGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBhc3luYyB0cmFjaW5nIGNv + bXBsZXRlIn1dfX19LCJvZmZzZXQiOiIxNSJ9AAAAAGV7Im9mZnNldCI6IjE2IiwiaW50ZXJhY3Rp + b25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1k + ZWx0YSIsInRva2VucyI6Nn19fQAAAACIeyJvZmZzZXQiOiIxNyIsInN0ZXAiOnsidHlwZSI6ImFz + c2lzdGFudE1lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdlIiwibWVzc2Fn + ZSI6eyJ0ZXh0IjoiY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19fQAAAACBeyJvZmZz + ZXQiOiIxOCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJzdGVwLWNvbXBsZXRlZCIsInVw + ZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJzdGVwSWQiOjIsInN0ZXBEdXJhdGlvbk1z + IjoxMDUwfX19AAAAALR7Im9mZnNldCI6IjE5IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6 + InR1cm4tZW5kZWQiLCJ1cGRhdGUiOnsidHlwZSI6InR1cm4tZW5kZWQiLCJ1c2FnZSI6eyJpbnB1 + dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDMsImNhY2hlUmVhZFRva2VucyI6ODM4NCwi + Y2FjaGVXcml0ZVRva2VucyI6MH19fX0AAAABJHsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2Ui + LCJtZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2 + Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNj + Ny05ODZjLWI1OTliOTJkZjBmZSIsInVzYWdlIjp7ImlucHV0VG9rZW5zIjoxMTM3Nywib3V0cHV0 + VG9rZW5zIjo0MywiY2FjaGVSZWFkVG9rZW5zIjo4Mzg0LCJjYWNoZVdyaXRlVG9rZW5zIjowLCJ0 + b3RhbFRva2VucyI6MTk4MDR9fX0sIm9mZnNldCI6IjIwIn0AAAAAynsic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2Vu + dC0yZjRjNzY5Zi0yZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5faWQiOiJydW4tMTNj + MDRjOTgtMjc2YS00M2M3LTk4NmMtYjU5OWI5MmRmMGZlIiwic3RhdHVzIjoiRklOSVNIRUQifX0s + Im9mZnNldCI6IjIxIn0AAAACMHsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC0yZjRjNzY5Zi0y + ZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQz + YzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5J + U0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5 + YjkyZGYwZmUiLCJhZ2VudElkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIy + YTRlYmE3Iiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXIt + Mi41In0sImR1cmF0aW9uTXMiOiIzMjMyIiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyODoz + MS40MDlaIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOiIxMTM3NyIsIm91dHB1dFRva2VucyI6IjQz + IiwiY2FjaGVSZWFkVG9rZW5zIjoiODM4NCIsInRvdGFsVG9rZW5zIjoiMTk4MDQifX19LCJvZmZz + ZXQiOiIyMiJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRi + ZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bklkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZj + LWI1OTliOTJkZjBmZSJ9LCJvZmZzZXQiOiIyMyJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:33 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[iter_text].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[iter_text].yaml new file mode 100644 index 00000000..8d4e4f48 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[iter_text].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:31 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAACAeyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fX0AAAAA + 2nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlu + a2luZyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fSwib2Zmc2V0IjoiMyJ9AAAAAGR7Im9m + ZnNldCI6IjQiLCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRh + dGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo1fX19AAAAAHl7Im9mZnNldCI6IjUi + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ1cGRhdGUiOnsi + dHlwZSI6InRoaW5raW5nLWRlbHRhIiwidGV4dCI6IiB0ZXh0IHJlcXVlc3RlZC4ifX19AAAAANN7 + InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJhZ2VudF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJh + NyIsInJ1bl9pZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJ0 + ZXh0IjoiIHRleHQgcmVxdWVzdGVkLiJ9fSwib2Zmc2V0IjoiNiJ9AAAAAGR7Im9mZnNldCI6Ijci + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlw + ZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo0fX19AAAAAKZ7Im9mZnNldCI6IjgiLCJzdGVwIjp7 + InR5cGUiOiJ0aGlua2luZ01lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJ0aGlua2luZ01lc3NhZ2Ui + LCJtZXNzYWdlIjp7InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCB0ZXh0IHJlcXVlc3Rl + ZC4iLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH57Im9mZnNldCI6IjkiLCJpbnRlcmFj + dGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctY29tcGxldGVkIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1jb21wbGV0ZWQiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX0AAAAA3Xsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIs + ImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3Iiwi + cnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsInRleHQi + OiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6MX19LCJvZmZzZXQiOiIxMCJ9AAAAAGh7Im9mZnNl + dCI6IjExIiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUi + OnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0IjoiY3Vyc29yIn19fQAAAAEHeyJzZGtNZXNzYWdl + Ijp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2Vu + dF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bl9p + ZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJtZXNzYWdlIjp7 + InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJz + b3IifV19fX0sIm9mZnNldCI6IjEyIn0AAAAAZXsib2Zmc2V0IjoiMTMiLCJpbnRlcmFjdGlvblVw + ZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRh + IiwidG9rZW5zIjoyfX19AAAAAHl7Im9mZnNldCI6IjE0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsi + dHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0Ijoi + IGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19AAAAARh7InNka01lc3NhZ2UiOnsidHlwZSI6ImFz + c2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQt + MmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0 + Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lz + dGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBhc3luYyB0cmFjaW5nIGNv + bXBsZXRlIn1dfX19LCJvZmZzZXQiOiIxNSJ9AAAAAGV7Im9mZnNldCI6IjE2IiwiaW50ZXJhY3Rp + b25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1k + ZWx0YSIsInRva2VucyI6Nn19fQAAAACIeyJvZmZzZXQiOiIxNyIsInN0ZXAiOnsidHlwZSI6ImFz + c2lzdGFudE1lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdlIiwibWVzc2Fn + ZSI6eyJ0ZXh0IjoiY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19fQAAAACBeyJvZmZz + ZXQiOiIxOCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJzdGVwLWNvbXBsZXRlZCIsInVw + ZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJzdGVwSWQiOjIsInN0ZXBEdXJhdGlvbk1z + IjoxMDUwfX19AAAAALR7Im9mZnNldCI6IjE5IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6 + InR1cm4tZW5kZWQiLCJ1cGRhdGUiOnsidHlwZSI6InR1cm4tZW5kZWQiLCJ1c2FnZSI6eyJpbnB1 + dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDMsImNhY2hlUmVhZFRva2VucyI6ODM4NCwi + Y2FjaGVXcml0ZVRva2VucyI6MH19fX0AAAABJHsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2Ui + LCJtZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2 + Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNj + Ny05ODZjLWI1OTliOTJkZjBmZSIsInVzYWdlIjp7ImlucHV0VG9rZW5zIjoxMTM3Nywib3V0cHV0 + VG9rZW5zIjo0MywiY2FjaGVSZWFkVG9rZW5zIjo4Mzg0LCJjYWNoZVdyaXRlVG9rZW5zIjowLCJ0 + b3RhbFRva2VucyI6MTk4MDR9fX0sIm9mZnNldCI6IjIwIn0AAAAAynsic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2Vu + dC0yZjRjNzY5Zi0yZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5faWQiOiJydW4tMTNj + MDRjOTgtMjc2YS00M2M3LTk4NmMtYjU5OWI5MmRmMGZlIiwic3RhdHVzIjoiRklOSVNIRUQifX0s + Im9mZnNldCI6IjIxIn0AAAACMHsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC0yZjRjNzY5Zi0y + ZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQz + YzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5J + U0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5 + YjkyZGYwZmUiLCJhZ2VudElkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIy + YTRlYmE3Iiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXIt + Mi41In0sImR1cmF0aW9uTXMiOiIzMjMyIiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyODoz + MS40MDlaIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOiIxMTM3NyIsIm91dHB1dFRva2VucyI6IjQz + IiwiY2FjaGVSZWFkVG9rZW5zIjoiODM4NCIsInRvdGFsVG9rZW5zIjoiMTk4MDQifX19LCJvZmZz + ZXQiOiIyMiJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRi + ZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bklkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZj + LWI1OTliOTJkZjBmZSJ9LCJvZmZzZXQiOiIyMyJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:33 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[iteration].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[iteration].yaml new file mode 100644 index 00000000..8d4e4f48 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[iteration].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:31 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAACAeyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fX0AAAAA + 2nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlu + a2luZyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fSwib2Zmc2V0IjoiMyJ9AAAAAGR7Im9m + ZnNldCI6IjQiLCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRh + dGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo1fX19AAAAAHl7Im9mZnNldCI6IjUi + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ1cGRhdGUiOnsi + dHlwZSI6InRoaW5raW5nLWRlbHRhIiwidGV4dCI6IiB0ZXh0IHJlcXVlc3RlZC4ifX19AAAAANN7 + InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJhZ2VudF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJh + NyIsInJ1bl9pZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJ0 + ZXh0IjoiIHRleHQgcmVxdWVzdGVkLiJ9fSwib2Zmc2V0IjoiNiJ9AAAAAGR7Im9mZnNldCI6Ijci + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlw + ZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo0fX19AAAAAKZ7Im9mZnNldCI6IjgiLCJzdGVwIjp7 + InR5cGUiOiJ0aGlua2luZ01lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJ0aGlua2luZ01lc3NhZ2Ui + LCJtZXNzYWdlIjp7InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCB0ZXh0IHJlcXVlc3Rl + ZC4iLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH57Im9mZnNldCI6IjkiLCJpbnRlcmFj + dGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctY29tcGxldGVkIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1jb21wbGV0ZWQiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX0AAAAA3Xsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIs + ImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3Iiwi + cnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsInRleHQi + OiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6MX19LCJvZmZzZXQiOiIxMCJ9AAAAAGh7Im9mZnNl + dCI6IjExIiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUi + OnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0IjoiY3Vyc29yIn19fQAAAAEHeyJzZGtNZXNzYWdl + Ijp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2Vu + dF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bl9p + ZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJtZXNzYWdlIjp7 + InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJz + b3IifV19fX0sIm9mZnNldCI6IjEyIn0AAAAAZXsib2Zmc2V0IjoiMTMiLCJpbnRlcmFjdGlvblVw + ZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRh + IiwidG9rZW5zIjoyfX19AAAAAHl7Im9mZnNldCI6IjE0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsi + dHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0Ijoi + IGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19AAAAARh7InNka01lc3NhZ2UiOnsidHlwZSI6ImFz + c2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQt + MmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0 + Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lz + dGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBhc3luYyB0cmFjaW5nIGNv + bXBsZXRlIn1dfX19LCJvZmZzZXQiOiIxNSJ9AAAAAGV7Im9mZnNldCI6IjE2IiwiaW50ZXJhY3Rp + b25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1k + ZWx0YSIsInRva2VucyI6Nn19fQAAAACIeyJvZmZzZXQiOiIxNyIsInN0ZXAiOnsidHlwZSI6ImFz + c2lzdGFudE1lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdlIiwibWVzc2Fn + ZSI6eyJ0ZXh0IjoiY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19fQAAAACBeyJvZmZz + ZXQiOiIxOCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJzdGVwLWNvbXBsZXRlZCIsInVw + ZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJzdGVwSWQiOjIsInN0ZXBEdXJhdGlvbk1z + IjoxMDUwfX19AAAAALR7Im9mZnNldCI6IjE5IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6 + InR1cm4tZW5kZWQiLCJ1cGRhdGUiOnsidHlwZSI6InR1cm4tZW5kZWQiLCJ1c2FnZSI6eyJpbnB1 + dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDMsImNhY2hlUmVhZFRva2VucyI6ODM4NCwi + Y2FjaGVXcml0ZVRva2VucyI6MH19fX0AAAABJHsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2Ui + LCJtZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2 + Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNj + Ny05ODZjLWI1OTliOTJkZjBmZSIsInVzYWdlIjp7ImlucHV0VG9rZW5zIjoxMTM3Nywib3V0cHV0 + VG9rZW5zIjo0MywiY2FjaGVSZWFkVG9rZW5zIjo4Mzg0LCJjYWNoZVdyaXRlVG9rZW5zIjowLCJ0 + b3RhbFRva2VucyI6MTk4MDR9fX0sIm9mZnNldCI6IjIwIn0AAAAAynsic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2Vu + dC0yZjRjNzY5Zi0yZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5faWQiOiJydW4tMTNj + MDRjOTgtMjc2YS00M2M3LTk4NmMtYjU5OWI5MmRmMGZlIiwic3RhdHVzIjoiRklOSVNIRUQifX0s + Im9mZnNldCI6IjIxIn0AAAACMHsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC0yZjRjNzY5Zi0y + ZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQz + YzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5J + U0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5 + YjkyZGYwZmUiLCJhZ2VudElkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIy + YTRlYmE3Iiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXIt + Mi41In0sImR1cmF0aW9uTXMiOiIzMjMyIiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyODoz + MS40MDlaIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOiIxMTM3NyIsIm91dHB1dFRva2VucyI6IjQz + IiwiY2FjaGVSZWFkVG9rZW5zIjoiODM4NCIsInRvdGFsVG9rZW5zIjoiMTk4MDQifX19LCJvZmZz + ZXQiOiIyMiJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRi + ZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bklkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZj + LWI1OTliOTJkZjBmZSJ9LCJvZmZzZXQiOiIyMyJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:33 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[stream].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[stream].yaml new file mode 100644 index 00000000..8d4e4f48 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[stream].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:31 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAACAeyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fX0AAAAA + 2nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlu + a2luZyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fSwib2Zmc2V0IjoiMyJ9AAAAAGR7Im9m + ZnNldCI6IjQiLCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRh + dGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo1fX19AAAAAHl7Im9mZnNldCI6IjUi + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ1cGRhdGUiOnsi + dHlwZSI6InRoaW5raW5nLWRlbHRhIiwidGV4dCI6IiB0ZXh0IHJlcXVlc3RlZC4ifX19AAAAANN7 + InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJhZ2VudF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJh + NyIsInJ1bl9pZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJ0 + ZXh0IjoiIHRleHQgcmVxdWVzdGVkLiJ9fSwib2Zmc2V0IjoiNiJ9AAAAAGR7Im9mZnNldCI6Ijci + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlw + ZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo0fX19AAAAAKZ7Im9mZnNldCI6IjgiLCJzdGVwIjp7 + InR5cGUiOiJ0aGlua2luZ01lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJ0aGlua2luZ01lc3NhZ2Ui + LCJtZXNzYWdlIjp7InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCB0ZXh0IHJlcXVlc3Rl + ZC4iLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH57Im9mZnNldCI6IjkiLCJpbnRlcmFj + dGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctY29tcGxldGVkIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1jb21wbGV0ZWQiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX0AAAAA3Xsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIs + ImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3Iiwi + cnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsInRleHQi + OiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6MX19LCJvZmZzZXQiOiIxMCJ9AAAAAGh7Im9mZnNl + dCI6IjExIiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUi + OnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0IjoiY3Vyc29yIn19fQAAAAEHeyJzZGtNZXNzYWdl + Ijp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2Vu + dF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bl9p + ZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJtZXNzYWdlIjp7 + InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJz + b3IifV19fX0sIm9mZnNldCI6IjEyIn0AAAAAZXsib2Zmc2V0IjoiMTMiLCJpbnRlcmFjdGlvblVw + ZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRh + IiwidG9rZW5zIjoyfX19AAAAAHl7Im9mZnNldCI6IjE0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsi + dHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0Ijoi + IGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19AAAAARh7InNka01lc3NhZ2UiOnsidHlwZSI6ImFz + c2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQt + MmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0 + Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lz + dGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBhc3luYyB0cmFjaW5nIGNv + bXBsZXRlIn1dfX19LCJvZmZzZXQiOiIxNSJ9AAAAAGV7Im9mZnNldCI6IjE2IiwiaW50ZXJhY3Rp + b25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1k + ZWx0YSIsInRva2VucyI6Nn19fQAAAACIeyJvZmZzZXQiOiIxNyIsInN0ZXAiOnsidHlwZSI6ImFz + c2lzdGFudE1lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdlIiwibWVzc2Fn + ZSI6eyJ0ZXh0IjoiY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19fQAAAACBeyJvZmZz + ZXQiOiIxOCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJzdGVwLWNvbXBsZXRlZCIsInVw + ZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJzdGVwSWQiOjIsInN0ZXBEdXJhdGlvbk1z + IjoxMDUwfX19AAAAALR7Im9mZnNldCI6IjE5IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6 + InR1cm4tZW5kZWQiLCJ1cGRhdGUiOnsidHlwZSI6InR1cm4tZW5kZWQiLCJ1c2FnZSI6eyJpbnB1 + dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDMsImNhY2hlUmVhZFRva2VucyI6ODM4NCwi + Y2FjaGVXcml0ZVRva2VucyI6MH19fX0AAAABJHsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2Ui + LCJtZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2 + Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNj + Ny05ODZjLWI1OTliOTJkZjBmZSIsInVzYWdlIjp7ImlucHV0VG9rZW5zIjoxMTM3Nywib3V0cHV0 + VG9rZW5zIjo0MywiY2FjaGVSZWFkVG9rZW5zIjo4Mzg0LCJjYWNoZVdyaXRlVG9rZW5zIjowLCJ0 + b3RhbFRva2VucyI6MTk4MDR9fX0sIm9mZnNldCI6IjIwIn0AAAAAynsic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2Vu + dC0yZjRjNzY5Zi0yZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5faWQiOiJydW4tMTNj + MDRjOTgtMjc2YS00M2M3LTk4NmMtYjU5OWI5MmRmMGZlIiwic3RhdHVzIjoiRklOSVNIRUQifX0s + Im9mZnNldCI6IjIxIn0AAAACMHsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC0yZjRjNzY5Zi0y + ZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQz + YzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5J + U0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5 + YjkyZGYwZmUiLCJhZ2VudElkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIy + YTRlYmE3Iiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXIt + Mi41In0sImR1cmF0aW9uTXMiOiIzMjMyIiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyODoz + MS40MDlaIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOiIxMTM3NyIsIm91dHB1dFRva2VucyI6IjQz + IiwiY2FjaGVSZWFkVG9rZW5zIjoiODM4NCIsInRvdGFsVG9rZW5zIjoiMTk4MDQifX19LCJvZmZz + ZXQiOiIyMiJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRi + ZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bklkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZj + LWI1OTliOTJkZjBmZSJ9LCJvZmZzZXQiOiIyMyJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:33 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[text].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[text].yaml new file mode 100644 index 00000000..8d4e4f48 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_consumption_paths_finalize_once[text].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:31 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAACAeyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fX0AAAAA + 2nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlu + a2luZyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fSwib2Zmc2V0IjoiMyJ9AAAAAGR7Im9m + ZnNldCI6IjQiLCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRh + dGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo1fX19AAAAAHl7Im9mZnNldCI6IjUi + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ1cGRhdGUiOnsi + dHlwZSI6InRoaW5raW5nLWRlbHRhIiwidGV4dCI6IiB0ZXh0IHJlcXVlc3RlZC4ifX19AAAAANN7 + InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJhZ2VudF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJh + NyIsInJ1bl9pZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJ0 + ZXh0IjoiIHRleHQgcmVxdWVzdGVkLiJ9fSwib2Zmc2V0IjoiNiJ9AAAAAGR7Im9mZnNldCI6Ijci + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlw + ZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo0fX19AAAAAKZ7Im9mZnNldCI6IjgiLCJzdGVwIjp7 + InR5cGUiOiJ0aGlua2luZ01lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJ0aGlua2luZ01lc3NhZ2Ui + LCJtZXNzYWdlIjp7InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCB0ZXh0IHJlcXVlc3Rl + ZC4iLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH57Im9mZnNldCI6IjkiLCJpbnRlcmFj + dGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctY29tcGxldGVkIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1jb21wbGV0ZWQiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX0AAAAA3Xsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIs + ImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3Iiwi + cnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsInRleHQi + OiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6MX19LCJvZmZzZXQiOiIxMCJ9AAAAAGh7Im9mZnNl + dCI6IjExIiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUi + OnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0IjoiY3Vyc29yIn19fQAAAAEHeyJzZGtNZXNzYWdl + Ijp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2Vu + dF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bl9p + ZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJtZXNzYWdlIjp7 + InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJz + b3IifV19fX0sIm9mZnNldCI6IjEyIn0AAAAAZXsib2Zmc2V0IjoiMTMiLCJpbnRlcmFjdGlvblVw + ZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRh + IiwidG9rZW5zIjoyfX19AAAAAHl7Im9mZnNldCI6IjE0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsi + dHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0Ijoi + IGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19AAAAARh7InNka01lc3NhZ2UiOnsidHlwZSI6ImFz + c2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQt + MmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0 + Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lz + dGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBhc3luYyB0cmFjaW5nIGNv + bXBsZXRlIn1dfX19LCJvZmZzZXQiOiIxNSJ9AAAAAGV7Im9mZnNldCI6IjE2IiwiaW50ZXJhY3Rp + b25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1k + ZWx0YSIsInRva2VucyI6Nn19fQAAAACIeyJvZmZzZXQiOiIxNyIsInN0ZXAiOnsidHlwZSI6ImFz + c2lzdGFudE1lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdlIiwibWVzc2Fn + ZSI6eyJ0ZXh0IjoiY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19fQAAAACBeyJvZmZz + ZXQiOiIxOCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJzdGVwLWNvbXBsZXRlZCIsInVw + ZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJzdGVwSWQiOjIsInN0ZXBEdXJhdGlvbk1z + IjoxMDUwfX19AAAAALR7Im9mZnNldCI6IjE5IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6 + InR1cm4tZW5kZWQiLCJ1cGRhdGUiOnsidHlwZSI6InR1cm4tZW5kZWQiLCJ1c2FnZSI6eyJpbnB1 + dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDMsImNhY2hlUmVhZFRva2VucyI6ODM4NCwi + Y2FjaGVXcml0ZVRva2VucyI6MH19fX0AAAABJHsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2Ui + LCJtZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2 + Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNj + Ny05ODZjLWI1OTliOTJkZjBmZSIsInVzYWdlIjp7ImlucHV0VG9rZW5zIjoxMTM3Nywib3V0cHV0 + VG9rZW5zIjo0MywiY2FjaGVSZWFkVG9rZW5zIjo4Mzg0LCJjYWNoZVdyaXRlVG9rZW5zIjowLCJ0 + b3RhbFRva2VucyI6MTk4MDR9fX0sIm9mZnNldCI6IjIwIn0AAAAAynsic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2Vu + dC0yZjRjNzY5Zi0yZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5faWQiOiJydW4tMTNj + MDRjOTgtMjc2YS00M2M3LTk4NmMtYjU5OWI5MmRmMGZlIiwic3RhdHVzIjoiRklOSVNIRUQifX0s + Im9mZnNldCI6IjIxIn0AAAACMHsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC0yZjRjNzY5Zi0y + ZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQz + YzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5J + U0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5 + YjkyZGYwZmUiLCJhZ2VudElkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIy + YTRlYmE3Iiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXIt + Mi41In0sImR1cmF0aW9uTXMiOiIzMjMyIiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyODoz + MS40MDlaIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOiIxMTM3NyIsIm91dHB1dFRva2VucyI6IjQz + IiwiY2FjaGVSZWFkVG9rZW5zIjoiODM4NCIsInRvdGFsVG9rZW5zIjoiMTk4MDQifX19LCJvZmZz + ZXQiOiIyMiJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRi + ZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bklkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZj + LWI1OTliOTJkZjBmZSJ9LCJvZmZzZXQiOiIyMyJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:33 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_messages_preserve_callbacks_and_trace.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_messages_preserve_callbacks_and_trace.yaml new file mode 100644 index 00000000..8d4e4f48 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_async_messages_preserve_callbacks_and_trace.yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:31 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAACAeyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fX0AAAAA + 2nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlu + a2luZyIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRl + YmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIs + InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCJ9fSwib2Zmc2V0IjoiMyJ9AAAAAGR7Im9m + ZnNldCI6IjQiLCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRh + dGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo1fX19AAAAAHl7Im9mZnNldCI6IjUi + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ1cGRhdGUiOnsi + dHlwZSI6InRoaW5raW5nLWRlbHRhIiwidGV4dCI6IiB0ZXh0IHJlcXVlc3RlZC4ifX19AAAAANN7 + InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJhZ2VudF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJh + NyIsInJ1bl9pZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJ0 + ZXh0IjoiIHRleHQgcmVxdWVzdGVkLiJ9fSwib2Zmc2V0IjoiNiJ9AAAAAGR7Im9mZnNldCI6Ijci + LCJpbnRlcmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlw + ZSI6InRva2VuLWRlbHRhIiwidG9rZW5zIjo0fX19AAAAAKZ7Im9mZnNldCI6IjgiLCJzdGVwIjp7 + InR5cGUiOiJ0aGlua2luZ01lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJ0aGlua2luZ01lc3NhZ2Ui + LCJtZXNzYWdlIjp7InRleHQiOiJSZXBseWluZyB3aXRoIHRoZSBleGFjdCB0ZXh0IHJlcXVlc3Rl + ZC4iLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH57Im9mZnNldCI6IjkiLCJpbnRlcmFj + dGlvblVwZGF0ZSI6eyJ0eXBlIjoidGhpbmtpbmctY29tcGxldGVkIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1jb21wbGV0ZWQiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX0AAAAA3Xsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIs + ImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3Iiwi + cnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsInRleHQi + OiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6MX19LCJvZmZzZXQiOiIxMCJ9AAAAAGh7Im9mZnNl + dCI6IjExIiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUi + OnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0IjoiY3Vyc29yIn19fQAAAAEHeyJzZGtNZXNzYWdl + Ijp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2Vu + dF9pZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRiZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bl9p + ZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJtZXNzYWdlIjp7 + InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJz + b3IifV19fX0sIm9mZnNldCI6IjEyIn0AAAAAZXsib2Zmc2V0IjoiMTMiLCJpbnRlcmFjdGlvblVw + ZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRh + IiwidG9rZW5zIjoyfX19AAAAAHl7Im9mZnNldCI6IjE0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsi + dHlwZSI6InRleHQtZGVsdGEiLCJ1cGRhdGUiOnsidHlwZSI6InRleHQtZGVsdGEiLCJ0ZXh0Ijoi + IGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19AAAAARh7InNka01lc3NhZ2UiOnsidHlwZSI6ImFz + c2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQt + MmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0 + Yzk4LTI3NmEtNDNjNy05ODZjLWI1OTliOTJkZjBmZSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lz + dGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBhc3luYyB0cmFjaW5nIGNv + bXBsZXRlIn1dfX19LCJvZmZzZXQiOiIxNSJ9AAAAAGV7Im9mZnNldCI6IjE2IiwiaW50ZXJhY3Rp + b25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1k + ZWx0YSIsInRva2VucyI6Nn19fQAAAACIeyJvZmZzZXQiOiIxNyIsInN0ZXAiOnsidHlwZSI6ImFz + c2lzdGFudE1lc3NhZ2UiLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdlIiwibWVzc2Fn + ZSI6eyJ0ZXh0IjoiY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxldGUifX19fQAAAACBeyJvZmZz + ZXQiOiIxOCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJzdGVwLWNvbXBsZXRlZCIsInVw + ZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJzdGVwSWQiOjIsInN0ZXBEdXJhdGlvbk1z + IjoxMDUwfX19AAAAALR7Im9mZnNldCI6IjE5IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6 + InR1cm4tZW5kZWQiLCJ1cGRhdGUiOnsidHlwZSI6InR1cm4tZW5kZWQiLCJ1c2FnZSI6eyJpbnB1 + dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDMsImNhY2hlUmVhZFRva2VucyI6ODM4NCwi + Y2FjaGVXcml0ZVRva2VucyI6MH19fX0AAAABJHsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2Ui + LCJtZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsImFnZW50X2lkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2 + Zi00ZGJkLWJlNjktZmVkNWIyYTRlYmE3IiwicnVuX2lkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNj + Ny05ODZjLWI1OTliOTJkZjBmZSIsInVzYWdlIjp7ImlucHV0VG9rZW5zIjoxMTM3Nywib3V0cHV0 + VG9rZW5zIjo0MywiY2FjaGVSZWFkVG9rZW5zIjo4Mzg0LCJjYWNoZVdyaXRlVG9rZW5zIjowLCJ0 + b3RhbFRva2VucyI6MTk4MDR9fX0sIm9mZnNldCI6IjIwIn0AAAAAynsic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2Vu + dC0yZjRjNzY5Zi0yZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5faWQiOiJydW4tMTNj + MDRjOTgtMjc2YS00M2M3LTk4NmMtYjU5OWI5MmRmMGZlIiwic3RhdHVzIjoiRklOSVNIRUQifX0s + Im9mZnNldCI6IjIxIn0AAAACMHsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC0yZjRjNzY5Zi0y + ZDZmLTRkYmQtYmU2OS1mZWQ1YjJhNGViYTciLCJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQz + YzctOTg2Yy1iNTk5YjkyZGYwZmUiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5J + U0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1bi0xM2MwNGM5OC0yNzZhLTQzYzctOTg2Yy1iNTk5 + YjkyZGYwZmUiLCJhZ2VudElkIjoiYWdlbnQtMmY0Yzc2OWYtMmQ2Zi00ZGJkLWJlNjktZmVkNWIy + YTRlYmE3Iiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXIt + Mi41In0sImR1cmF0aW9uTXMiOiIzMjMyIiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyODoz + MS40MDlaIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOiIxMTM3NyIsIm91dHB1dFRva2VucyI6IjQz + IiwiY2FjaGVSZWFkVG9rZW5zIjoiODM4NCIsInRvdGFsVG9rZW5zIjoiMTk4MDQifX19LCJvZmZz + ZXQiOiIyMiJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTJmNGM3NjlmLTJkNmYtNGRi + ZC1iZTY5LWZlZDViMmE0ZWJhNyIsInJ1bklkIjoicnVuLTEzYzA0Yzk4LTI3NmEtNDNjNy05ODZj + LWI1OTliOTJkZjBmZSJ9LCJvZmZzZXQiOiIyMyJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:33 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-2f4c769f-2d6f-4dbd-be69-fed5b2a4eba7"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:34 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_auto_cursor_sdk.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_auto_cursor_sdk.yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_auto_cursor_sdk.yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_builtin_tool_events_create_one_tool_span.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_builtin_tool_events_create_one_tool_span.yaml new file mode 100644 index 00000000..4080751f --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_builtin_tool_events_create_one_tool_span.yaml @@ -0,0 +1,236 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-5d3f4fc7-2afe-4674-a0a3-e1924172af9e","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:35 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAMt7ImFnZW50SWQiOiAiYWdlbnQtNWQzZjRmYzctMmFmZS00Njc0LWEwYTMtZTE5MjQxNzJh + ZjllIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiVXNlIHRoZSBzaGVsbCB0b29sIHRvIHJ1biBgcHJp + bnRmIGN1cnNvci10b29sLWNvbXBsZXRlYCwgdGhlbiByZXBseSB3aXRoIHRoZSBvdXRwdXQuIn0s + ICJvcHRpb25zIjogeyJhcGlLZXkiOiAiPFJFREFDVEVEPiJ9fQ== + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '267' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNWQzZjRmYzctMmFmZS00Njc0LWEwYTMtZTE5MjQxNzJh + ZjllIiwicnVuX2lkIjoicnVuLTMyMDA5ZmEwLWRmN2QtNDQ1MC1iMjM5LTg3ODQ5YTRkNzJhZCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADoeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC01ZDNmNGZjNy0yYWZlLTQ2NzQtYTBhMy1lMTkyNDE3MmFmOWUiLCJydW5faWQiOiJydW4t + MzIwMDlmYTAtZGY3ZC00NDUwLWIyMzktODc4NDlhNGQ3MmFkIiwidGV4dCI6IlJ1bm5pbmcgYHBy + aW50ZiBjdXJzb3ItdG9vbC1jb21wbGV0ZWAifX0sIm9mZnNldCI6IjIifQAAAADXeyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdl + bnRfaWQiOiJhZ2VudC01ZDNmNGZjNy0yYWZlLTQ2NzQtYTBhMy1lMTkyNDE3MmFmOWUiLCJydW5f + aWQiOiJydW4tMzIwMDlmYTAtZGY3ZC00NDUwLWIyMzktODc4NDlhNGQ3MmFkIiwidGV4dCI6IiB2 + aWEgdGhlIHNoZWxsIHRvb2wgIn19LCJvZmZzZXQiOiIzIn0AAAAA13sic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoi + YWdlbnQtNWQzZjRmYzctMmFmZS00Njc0LWEwYTMtZTE5MjQxNzJhZjllIiwicnVuX2lkIjoicnVu + LTMyMDA5ZmEwLWRmN2QtNDQ1MC1iMjM5LTg3ODQ5YTRkNzJhZCIsInRleHQiOiJhbmQgd2lsbCBy + ZXBseSB3aXRoICJ9fSwib2Zmc2V0IjoiNCJ9AAAAAM57InNka01lc3NhZ2UiOnsidHlwZSI6InRo + aW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTVk + M2Y0ZmM3LTJhZmUtNDY3NC1hMGEzLWUxOTI0MTcyYWY5ZSIsInJ1bl9pZCI6InJ1bi0zMjAwOWZh + MC1kZjdkLTQ0NTAtYjIzOS04Nzg0OWE0ZDcyYWQiLCJ0ZXh0IjoidGhlIG91dHB1dC4ifX0sIm9m + ZnNldCI6IjUifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC01ZDNmNGZjNy0yYWZlLTQ2NzQt + YTBhMy1lMTkyNDE3MmFmOWUiLCJydW5faWQiOiJydW4tMzIwMDlmYTAtZGY3ZC00NDUwLWIyMzkt + ODc4NDlhNGQ3MmFkIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjYifQAAAAFTeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0b29sX2NhbGwiLCJtZXNzYWdlIjp7 + InR5cGUiOiJ0b29sX2NhbGwiLCJhZ2VudF9pZCI6ImFnZW50LTVkM2Y0ZmM3LTJhZmUtNDY3NC1h + MGEzLWUxOTI0MTcyYWY5ZSIsInJ1bl9pZCI6InJ1bi0zMjAwOWZhMC1kZjdkLTQ0NTAtYjIzOS04 + Nzg0OWE0ZDcyYWQiLCJjYWxsX2lkIjoidG9vbF9iYTAyZjFiZS1hMjlkLTQwZWEtOTIxZi1kMzQz + N2FjZDk4NyIsIm5hbWUiOiJzaGVsbCIsInN0YXR1cyI6InJ1bm5pbmciLCJhcmdzIjp7ImNvbW1h + bmQiOiJwcmludGYgY3Vyc29yLXRvb2wtY29tcGxldGUiLCJ0aW1lb3V0IjozMDAwMH19fSwib2Zm + c2V0IjoiNyJ9AAAAAdZ7InNka01lc3NhZ2UiOnsidHlwZSI6InRvb2xfY2FsbCIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRvb2xfY2FsbCIsImFnZW50X2lkIjoiYWdlbnQtNWQzZjRmYzctMmFmZS00Njc0 + LWEwYTMtZTE5MjQxNzJhZjllIiwicnVuX2lkIjoicnVuLTMyMDA5ZmEwLWRmN2QtNDQ1MC1iMjM5 + LTg3ODQ5YTRkNzJhZCIsImNhbGxfaWQiOiJ0b29sX2JhMDJmMWJlLWEyOWQtNDBlYS05MjFmLWQz + NDM3YWNkOTg3IiwibmFtZSI6InNoZWxsIiwic3RhdHVzIjoiY29tcGxldGVkIiwiYXJncyI6eyJj + b21tYW5kIjoicHJpbnRmIGN1cnNvci10b29sLWNvbXBsZXRlIiwidGltZW91dCI6MzAwMDB9LCJy + ZXN1bHQiOnsic3RhdHVzIjoic3VjY2VzcyIsInZhbHVlIjp7ImV4aXRDb2RlIjowLCJzaWduYWwi + OiIiLCJzdGRvdXQiOiJjdXJzb3ItdG9vbC1jb21wbGV0ZSIsInN0ZGVyciI6IiIsImV4ZWN1dGlv + blRpbWUiOjk3Nn19fX0sIm9mZnNldCI6IjgifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0 + aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC01 + ZDNmNGZjNy0yYWZlLTQ2NzQtYTBhMy1lMTkyNDE3MmFmOWUiLCJydW5faWQiOiJydW4tMzIwMDlm + YTAtZGY3ZC00NDUwLWIyMzktODc4NDlhNGQ3MmFkIiwidGV4dCI6IlRoZSBjb21tYW5kIHByaW50 + ZWQgIn19LCJvZmZzZXQiOiI5In0AAAAA3Xsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmci + LCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtNWQzZjRmYzct + MmFmZS00Njc0LWEwYTMtZTE5MjQxNzJhZjllIiwicnVuX2lkIjoicnVuLTMyMDA5ZmEwLWRmN2Qt + NDQ1MC1iMjM5LTg3ODQ5YTRkNzJhZCIsInRleHQiOiJcImN1cnNvci10b29sLWNvbXBsZXRlXCIu + In19LCJvZmZzZXQiOiIxMCJ9AAAAAN17InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwi + bWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTVkM2Y0ZmM3LTJh + ZmUtNDY3NC1hMGEzLWUxOTI0MTcyYWY5ZSIsInJ1bl9pZCI6InJ1bi0zMjAwOWZhMC1kZjdkLTQ0 + NTAtYjIzOS04Nzg0OWE0ZDcyYWQiLCJ0ZXh0IjoiIiwidGhpbmtpbmdfZHVyYXRpb25fbXMiOjF9 + fSwib2Zmc2V0IjoiMTEifQAAAAEHeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJt + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTVkM2Y0ZmM3LTJh + ZmUtNDY3NC1hMGEzLWUxOTI0MTcyYWY5ZSIsInJ1bl9pZCI6InJ1bi0zMjAwOWZhMC1kZjdkLTQ0 + NTAtYjIzOS04Nzg0OWE0ZDcyYWQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250 + ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjEyIn0A + AAABBnsic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoi + YXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC01ZDNmNGZjNy0yYWZlLTQ2NzQtYTBhMy1lMTky + NDE3MmFmOWUiLCJydW5faWQiOiJydW4tMzIwMDlmYTAtZGY3ZC00NDUwLWIyMzktODc4NDlhNGQ3 + MmFkIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRl + eHQiLCJ0ZXh0IjoiLXRvb2wifV19fX0sIm9mZnNldCI6IjEzIn0AAAABCnsic2RrTWVzc2FnZSI6 + eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwiYWdlbnRf + aWQiOiJhZ2VudC01ZDNmNGZjNy0yYWZlLTQ2NzQtYTBhMy1lMTkyNDE3MmFmOWUiLCJydW5faWQi + OiJydW4tMzIwMDlmYTAtZGY3ZC00NDUwLWIyMzktODc4NDlhNGQ3MmFkIiwibWVzc2FnZSI6eyJy + b2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiLWNvbXBs + ZXRlIn1dfX19LCJvZmZzZXQiOiIxNCJ9AAAAASV7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdl + IiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTVkM2Y0ZmM3LTJh + ZmUtNDY3NC1hMGEzLWUxOTI0MTcyYWY5ZSIsInJ1bl9pZCI6InJ1bi0zMjAwOWZhMC1kZjdkLTQ0 + NTAtYjIzOS04Nzg0OWE0ZDcyYWQiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MjI4NzAsIm91dHB1 + dFRva2VucyI6ODAsImNhY2hlUmVhZFRva2VucyI6MTU2ODAsImNhY2hlV3JpdGVUb2tlbnMiOjAs + InRvdGFsVG9rZW5zIjozODYzMH19fSwib2Zmc2V0IjoiMTUifQAAAADKeyJzZGtNZXNzYWdlIjp7 + InR5cGUiOiJzdGF0dXMiLCJtZXNzYWdlIjp7InR5cGUiOiJzdGF0dXMiLCJhZ2VudF9pZCI6ImFn + ZW50LTVkM2Y0ZmM3LTJhZmUtNDY3NC1hMGEzLWUxOTI0MTcyYWY5ZSIsInJ1bl9pZCI6InJ1bi0z + MjAwOWZhMC1kZjdkLTQ0NTAtYjIzOS04Nzg0OWE0ZDcyYWQiLCJzdGF0dXMiOiJGSU5JU0hFRCJ9 + fSwib2Zmc2V0IjoiMTYifQAAAAIoeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50LTVkM2Y0ZmM3 + LTJhZmUtNDY3NC1hMGEzLWUxOTI0MTcyYWY5ZSIsInJ1bklkIjoicnVuLTMyMDA5ZmEwLWRmN2Qt + NDQ1MC1iMjM5LTg3ODQ5YTRkNzJhZCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJ + TklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTMyMDA5ZmEwLWRmN2QtNDQ1MC1iMjM5LTg3 + ODQ5YTRkNzJhZCIsImFnZW50SWQiOiJhZ2VudC01ZDNmNGZjNy0yYWZlLTQ2NzQtYTBhMy1lMTky + NDE3MmFmOWUiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3Vs + dCI6ImN1cnNvci10b29sLWNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21wb3Nlci0yLjUifSwi + ZHVyYXRpb25NcyI6IjU0ODgiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIwOjI4OjM1LjgzMloi + LCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjIyODcwIiwib3V0cHV0VG9rZW5zIjoiODAiLCJjYWNo + ZVJlYWRUb2tlbnMiOiIxNTY4MCIsInRvdGFsVG9rZW5zIjoiMzg2MzAifX19LCJvZmZzZXQiOiIx + NyJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTVkM2Y0ZmM3LTJhZmUtNDY3NC1hMGEz + LWUxOTI0MTcyYWY5ZSIsInJ1bklkIjoicnVuLTMyMDA5ZmEwLWRmN2QtNDQ1MC1iMjM5LTg3ODQ5 + YTRkNzJhZCJ9LCJvZmZzZXQiOiIxOCJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:37 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-5d3f4fc7-2afe-4674-a0a3-e1924172af9e"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:41 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:41 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_characterize_no_downstream_provider_spans.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_characterize_no_downstream_provider_spans.yaml new file mode 100644 index 00000000..078b092c --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_characterize_no_downstream_provider_spans.yaml @@ -0,0 +1,197 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-ea5fe131-ecbc-4096-8d61-449eb3e2c30c","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:22 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKt7ImFnZW50SWQiOiAiYWdlbnQtZWE1ZmUxMzEtZWNiYy00MDk2LThkNjEtNDQ5ZWIzZTJj + MzBjIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgY2hh + cmFjdGVyaXphdGlvbiBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RF + RD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '235' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtZWE1ZmUxMzEtZWNiYy00MDk2LThkNjEtNDQ5ZWIzZTJj + MzBjIiwicnVuX2lkIjoicnVuLWUzNTBjYmViLWJkNzctNDVhNC05ZTE0LThiYWM4MWMzYWFhNCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1lYTVmZTEzMS1lY2JjLTQwOTYtOGQ2MS00NDllYjNlMmMzMGMiLCJydW5faWQiOiJydW4t + ZTM1MGNiZWItYmQ3Ny00NWE0LTllMTQtOGJhYzgxYzNhYWE0IiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA5nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + ZWE1ZmUxMzEtZWNiYy00MDk2LThkNjEtNDQ5ZWIzZTJjMzBjIiwicnVuX2lkIjoicnVuLWUzNTBj + YmViLWJkNzctNDVhNC05ZTE0LThiYWM4MWMzYWFhNCIsInRleHQiOiIgZXhhY3RseTogXCJjdXJz + b3IgY2hhcmFjdGVyaXphdGlvbiJ9fSwib2Zmc2V0IjoiMyJ9AAAAAM57InNka01lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6 + ImFnZW50LWVhNWZlMTMxLWVjYmMtNDA5Ni04ZDYxLTQ0OWViM2UyYzMwYyIsInJ1bl9pZCI6InJ1 + bi1lMzUwY2JlYi1iZDc3LTQ1YTQtOWUxNC04YmFjODFjM2FhYTQiLCJ0ZXh0IjoiIGNvbXBsZXRl + XCIifX0sIm9mZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIs + Im1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1lYTVmZTEzMS1l + Y2JjLTQwOTYtOGQ2MS00NDllYjNlMmMzMGMiLCJydW5faWQiOiJydW4tZTM1MGNiZWItYmQ3Ny00 + NWE0LTllMTQtOGJhYzgxYzNhYWE0IiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjox + fX0sIm9mZnNldCI6IjUifQAAAAEgeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJt + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWVhNWZlMTMxLWVj + YmMtNDA5Ni04ZDYxLTQ0OWViM2UyYzMwYyIsInJ1bl9pZCI6InJ1bi1lMzUwY2JlYi1iZDc3LTQ1 + YTQtOWUxNC04YmFjODFjM2FhYTQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250 + ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IgY2hhcmFjdGVyaXphdGlvbiBjb21w + bGV0ZSJ9XX19fSwib2Zmc2V0IjoiNiJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdl + IiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LWVhNWZlMTMxLWVj + YmMtNDA5Ni04ZDYxLTQ0OWViM2UyYzMwYyIsInJ1bl9pZCI6InJ1bi1lMzUwY2JlYi1iZDc3LTQ1 + YTQtOWUxNC04YmFjODFjM2FhYTQiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1 + dFRva2VucyI6MzgsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwi + dG90YWxUb2tlbnMiOjE5ODMxfX19LCJvZmZzZXQiOiI3In0AAAAAyXsic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2Vu + dC1lYTVmZTEzMS1lY2JjLTQwOTYtOGQ2MS00NDllYjNlMmMzMGMiLCJydW5faWQiOiJydW4tZTM1 + MGNiZWItYmQ3Ny00NWE0LTllMTQtOGJhYzgxYzNhYWE0Iiwic3RhdHVzIjoiRklOSVNIRUQifX0s + Im9mZnNldCI6IjgifQAAAAIyeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50LWVhNWZlMTMxLWVj + YmMtNDA5Ni04ZDYxLTQ0OWViM2UyYzMwYyIsInJ1bklkIjoicnVuLWUzNTBjYmViLWJkNzctNDVh + NC05ZTE0LThiYWM4MWMzYWFhNCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklT + SEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLWUzNTBjYmViLWJkNzctNDVhNC05ZTE0LThiYWM4 + MWMzYWFhNCIsImFnZW50SWQiOiJhZ2VudC1lYTVmZTEzMS1lY2JjLTQwOTYtOGQ2MS00NDllYjNl + MmMzMGMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6 + ImN1cnNvciBjaGFyYWN0ZXJpemF0aW9uIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21wb3Nl + ci0yLjUifSwiZHVyYXRpb25NcyI6IjI3MTgiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIwOjI4 + OjIyLjA4M1oiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzc3Iiwib3V0cHV0VG9rZW5zIjoi + MzgiLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzMSJ9fX0sIm9m + ZnNldCI6IjkifQAAAACCeyJkb25lIjp7ImFnZW50SWQiOiJhZ2VudC1lYTVmZTEzMS1lY2JjLTQw + OTYtOGQ2MS00NDllYjNlMmMzMGMiLCJydW5JZCI6InJ1bi1lMzUwY2JlYi1iZDc3LTQ1YTQtOWUx + NC04YmFjODFjM2FhYTQifSwib2Zmc2V0IjoiMTAifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-ea5fe131-ecbc-4096-8d61-449eb3e2c30c"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_custom_tool_dispatch_traces_under_the_agents_run.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_custom_tool_dispatch_traces_under_the_agents_run.yaml new file mode 100644 index 00000000..f2497560 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_custom_tool_dispatch_traces_under_the_agents_run.yaml @@ -0,0 +1,306 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-032e5138-2b7d-4166-8ec8-d7f36db937b2","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Thu, 06 Aug 2026 15:25:59 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtMDMyZTUxMzgtMmI3ZC00MTY2LThlYzgtZDdmMzZkYjkz + N2IyIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMDMyZTUxMzgtMmI3ZC00MTY2LThlYzgtZDdmMzZkYjkz + N2IyIiwicnVuX2lkIjoicnVuLTYyNTRlZGMzLWM2ZjQtNGU5ZC04MzE0LTE1ZDE3ZjQ5NjE3NiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC0wMzJlNTEzOC0yYjdkLTQxNjYtOGVjOC1kN2YzNmRiOTM3YjIiLCJydW5faWQiOiJydW4t + NjI1NGVkYzMtYzZmNC00ZTlkLTgzMTQtMTVkMTdmNDk2MTc2IiwidGV4dCI6IlRoZSB1c2VyIHJl + cXVlc3RlZCBhIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtMDMy + ZTUxMzgtMmI3ZC00MTY2LThlYzgtZDdmMzZkYjkzN2IyIiwicnVuX2lkIjoicnVuLTYyNTRlZGMz + LWM2ZjQtNGU5ZC04MzE0LTE1ZDE3ZjQ5NjE3NiIsInRleHQiOiIgcmVwbHkgY29udGFpbmluZyBl + eGFjdGx5In19LCJvZmZzZXQiOiIzIn0AAAAA3Xsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtMDMyZTUx + MzgtMmI3ZC00MTY2LThlYzgtZDdmMzZkYjkzN2IyIiwicnVuX2lkIjoicnVuLTYyNTRlZGMzLWM2 + ZjQtNGU5ZC04MzE0LTE1ZDE3ZjQ5NjE3NiIsInRleHQiOiIgdGhlIHRleHQgXCJjdXJzb3IgdHJh + Y2luZyJ9fSwib2Zmc2V0IjoiNCJ9AAAAAM97InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5n + IiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTAzMmU1MTM4 + LTJiN2QtNDE2Ni04ZWM4LWQ3ZjM2ZGI5MzdiMiIsInJ1bl9pZCI6InJ1bi02MjU0ZWRjMy1jNmY0 + LTRlOWQtODMxNC0xNWQxN2Y0OTYxNzYiLCJ0ZXh0IjoiIGNvbXBsZXRlXCIuIn19LCJvZmZzZXQi + OiI1In0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtMDMyZTUxMzgtMmI3ZC00MTY2LThlYzgt + ZDdmMzZkYjkzN2IyIiwicnVuX2lkIjoicnVuLTYyNTRlZGMzLWM2ZjQtNGU5ZC04MzE0LTE1ZDE3 + ZjQ5NjE3NiIsInRleHQiOiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6Mn19LCJvZmZzZXQiOiI2 + In0AAAABF3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBl + IjoiYXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC0wMzJlNTEzOC0yYjdkLTQxNjYtOGVjOC1k + N2YzNmRiOTM3YjIiLCJydW5faWQiOiJydW4tNjI1NGVkYzMtYzZmNC00ZTlkLTgzMTQtMTVkMTdm + NDk2MTc2IiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6 + InRleHQiLCJ0ZXh0IjoiY3Vyc29yIHRyYWNpbmcgY29tcGxldGUifV19fX0sIm9mZnNldCI6Ijci + fQAAAAEjeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsIm1lc3NhZ2UiOnsidHlwZSI6InVz + YWdlIiwiYWdlbnRfaWQiOiJhZ2VudC0wMzJlNTEzOC0yYjdkLTQxNjYtOGVjOC1kN2YzNmRiOTM3 + YjIiLCJydW5faWQiOiJydW4tNjI1NGVkYzMtYzZmNC00ZTlkLTgzMTQtMTVkMTdmNDk2MTc2Iiwi + dXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExMzkyLCJvdXRwdXRUb2tlbnMiOjM4LCJjYWNoZVJlYWRU + b2tlbnMiOjg0MTYsImNhY2hlV3JpdGVUb2tlbnMiOjAsInRvdGFsVG9rZW5zIjoxOTg0Nn19fSwi + b2Zmc2V0IjoiOCJ9AAAAAMl7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMDMyZTUxMzgtMmI3ZC00MTY2LThl + YzgtZDdmMzZkYjkzN2IyIiwicnVuX2lkIjoicnVuLTYyNTRlZGMzLWM2ZjQtNGU5ZC04MzE0LTE1 + ZDE3ZjQ5NjE3NiIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiI5In0AAAACKnsicmVz + dWx0Ijp7ImFnZW50SWQiOiJhZ2VudC0wMzJlNTEzOC0yYjdkLTQxNjYtOGVjOC1kN2YzNmRiOTM3 + YjIiLCJydW5JZCI6InJ1bi02MjU0ZWRjMy1jNmY0LTRlOWQtODMxNC0xNWQxN2Y0OTYxNzYiLCJz + dGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6eyJydW5JZCI6 + InJ1bi02MjU0ZWRjMy1jNmY0LTRlOWQtODMxNC0xNWQxN2Y0OTYxNzYiLCJhZ2VudElkIjoiYWdl + bnQtMDMyZTUxMzgtMmI3ZC00MTY2LThlYzgtZDdmMzZkYjkzN2IyIiwic3RhdHVzIjoiUlVOX0xJ + RkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3IgdHJhY2luZyBjb21wbGV0 + ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9uTXMiOiI0NDY5IiwiY3Jl + YXRlZEF0IjoiMjAyNi0wOC0wNlQxNToyNTo1OS4zMjVaIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMi + OiIxMTM5MiIsIm91dHB1dFRva2VucyI6IjM4IiwiY2FjaGVSZWFkVG9rZW5zIjoiODQxNiIsInRv + dGFsVG9rZW5zIjoiMTk4NDYifX19LCJvZmZzZXQiOiIxMCJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJ + ZCI6ImFnZW50LTAzMmU1MTM4LTJiN2QtNDE2Ni04ZWM4LWQ3ZjM2ZGI5MzdiMiIsInJ1bklkIjoi + cnVuLTYyNTRlZGMzLWM2ZjQtNGU5ZC04MzE0LTE1ZDE3ZjQ5NjE3NiJ9LCJvZmZzZXQiOiIxMSJ9 + AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Thu, 06 Aug 2026 15:26:01 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-032e5138-2b7d-4166-8ec8-d7f36db937b2"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Thu, 06 Aug 2026 15:26:03 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-NzQ5MmI3YzktMGVkOC00YTg2LTg0YmQtNzg3ZmQzMTM4NjRk'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 06 Aug 2026 15:26:04 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Bt-Was-Udf-Cached: + - 'true' + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - NzQ5MmI3YzktMGVkOC00YTg2LTg0YmQtNzg3ZmQzMTM4NjRk + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::sh6mm-1786029964176-f729c529060c + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + User-Agent: + - python-requests/2.34.2 + method: GET + uri: https://cursor-sdk-bridge/version + response: + body: + string: '{"version":"2.9.0","date_version":"20260805","ff_version":44,"commit":"787a5ad8b0dd2090d79c37513ba5cc3d21758ddc","deployment_mode":"lambda","deployment_type":"custom","brainstore_default":"force","brainstore_can_contain_row_refs":true,"skip_pg_config":"all","has_realtime_wal_bucket":true,"brainstore_wal_footer_version":"v3","brainstore_wal_use_efficient_format":true,"has_logs2":true,"brainstore_export_enabled":true,"js":true,"universal":true,"code_execution":true,"logs3_payload_max_bytes":5242880,"control_plane_telemetry":["status","memprof","usage"]}' + headers: + Connection: + - keep-alive + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 06 Aug 2026 15:26:04 GMT + Via: + - 1.1 7b609f6f2da1597a3efb21b332d7ce54.cloudfront.net (CloudFront), 1.1 dcd16c430149132ea12a5783d54ff114.cloudfront.net + (CloudFront) + X-Amz-Cf-Id: + - Ngs1j-TTDprUfdagJJSvGgxXL67ZgrQVCrkVgYlUr2DV032j52vukA== + X-Amz-Cf-Pop: + - YTO53-P2 + - YTO50-P2 + X-Amzn-Trace-Id: + - Root=1-6a74a78c-4259a07a134ab94e15b3074e;Parent=7b0c0818204e78d6;Sampled=0;Lineage=1:24be3d11:0 + X-Cache: + - Miss from cloudfront + access-control-allow-credentials: + - 'true' + access-control-expose-headers: + - x-bt-cursor,x-bt-found-existing,x-bt-query-plan,x-bt-api-duration-ms,x-bt-brainstore-duration-ms,x-bt-internal-trace-id,x-bt-error-origin,x-bt-used-endpoint,x-bt-overflow-url + cache-control: + - no-store, no-cache, must-revalidate, proxy-revalidate + content-length: + - '557' + etag: + - W/"22d-RtkjTszsylxX5VGRelXw9TnJwV8" + expires: + - '0' + surrogate-control: + - no-store + vary: + - Origin + x-amz-apigw-id: + - Br8eAFl4IAMEqIA= + x-amzn-Remapped-content-length: + - '557' + x-amzn-RequestId: + - 52a3ca3a-bbf2-4a87-a3e8-d2b8cb00ba6b + x-bt-internal-trace-id: + - 6a74a78c0000000062cfbda97bdf6df8 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_multimodal_input_materializes_attachment.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_multimodal_input_materializes_attachment.yaml new file mode 100644 index 00000000..0ccdefc7 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_multimodal_input_materializes_attachment.yaml @@ -0,0 +1,257 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-76010b2d-f3e0-46b5-bba7-9d1f9874a94e","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:01:31 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAN17ImFnZW50SWQiOiAiYWdlbnQtNzYwMTBiMmQtZjNlMC00NmI1LWJiYTctOWQxZjk4NzRh + OTRlIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiQnJpZWZseSBkZXNjcmliZSB0aGlzIGltYWdlLiIs + ICJpbWFnZXMiOiBbeyJkYXRhIjogeyJkYXRhIjogIjxCQVNFNjRfREFUQT4iLCAibWltZVR5cGUi + OiAiaW1hZ2UvcG5nIn19XX0sICJvcHRpb25zIjogeyJhcGlLZXkiOiAiPFJFREFDVEVEPiJ9fQ== + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '364' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNzYwMTBiMmQtZjNlMC00NmI1LWJiYTctOWQxZjk4NzRh + OTRlIiwicnVuX2lkIjoicnVuLTZiYTVmNGM0LTJmNjYtNGVkMy05YjA3LTBhNzM4OGMxYTdhZCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADZeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC03NjAxMGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5faWQiOiJydW4t + NmJhNWY0YzQtMmY2Ni00ZWQzLTliMDctMGE3Mzg4YzFhN2FkIiwidGV4dCI6IlRoZSB1c2VyIHdh + bnRzIGEgYnJpZWYifX0sIm9mZnNldCI6IjIifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0 + aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC03 + NjAxMGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5faWQiOiJydW4tNmJhNWY0 + YzQtMmY2Ni00ZWQzLTliMDctMGE3Mzg4YzFhN2FkIiwidGV4dCI6IiBkZXNjcmlwdGlvbiBvZiBh + biBpbWFnZS4ifX0sIm9mZnNldCI6IjMifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlu + a2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC03NjAx + MGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5faWQiOiJydW4tNmJhNWY0YzQt + MmY2Ni00ZWQzLTliMDctMGE3Mzg4YzFhN2FkIiwidGV4dCI6IlxuXG5UaGUgaW1hZ2UgaXMgYSBz + b2xpZCwifX0sIm9mZnNldCI6IjQifQAAAADYeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2lu + ZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC03NjAxMGIy + ZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5faWQiOiJydW4tNmJhNWY0YzQtMmY2 + Ni00ZWQzLTliMDctMGE3Mzg4YzFhN2FkIiwidGV4dCI6IiB1bmlmb3JtIGJsYWNrIHNxdWFyZSJ9 + fSwib2Zmc2V0IjoiNSJ9AAAAANl7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVz + c2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTc2MDEwYjJkLWYzZTAt + NDZiNS1iYmE3LTlkMWY5ODc0YTk0ZSIsInJ1bl9pZCI6InJ1bi02YmE1ZjRjNC0yZjY2LTRlZDMt + OWIwNy0wYTczODhjMWE3YWQiLCJ0ZXh0IjoiIHdpdGggbm8gb3RoZXIgc2hhcGVzLCJ9fSwib2Zm + c2V0IjoiNiJ9AAAAANh7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6 + eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTc2MDEwYjJkLWYzZTAtNDZiNS1i + YmE3LTlkMWY5ODc0YTk0ZSIsInJ1bl9pZCI6InJ1bi02YmE1ZjRjNC0yZjY2LTRlZDMtOWIwNy0w + YTczODhjMWE3YWQiLCJ0ZXh0IjoiIGNvbG9ycywgb3IgZmVhdHVyZXMuIn19LCJvZmZzZXQiOiI3 + In0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUi + OiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtNzYwMTBiMmQtZjNlMC00NmI1LWJiYTctOWQx + Zjk4NzRhOTRlIiwicnVuX2lkIjoicnVuLTZiYTVmNGM0LTJmNjYtNGVkMy05YjA3LTBhNzM4OGMx + YTdhZCIsInRleHQiOiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6MX19LCJvZmZzZXQiOiI4In0A + AAABBHsic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoi + YXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC03NjAxMGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFm + OTg3NGE5NGUiLCJydW5faWQiOiJydW4tNmJhNWY0YzQtMmY2Ni00ZWQzLTliMDctMGE3Mzg4YzFh + N2FkIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRl + eHQiLCJ0ZXh0IjoiVGhpcyJ9XX19fSwib2Zmc2V0IjoiOSJ9AAAAAQd7InNka01lc3NhZ2UiOnsi + dHlwZSI6ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lk + IjoiYWdlbnQtNzYwMTBiMmQtZjNlMC00NmI1LWJiYTctOWQxZjk4NzRhOTRlIiwicnVuX2lkIjoi + cnVuLTZiYTVmNGM0LTJmNjYtNGVkMy05YjA3LTBhNzM4OGMxYTdhZCIsIm1lc3NhZ2UiOnsicm9s + ZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBpbWFnZSJ9 + XX19fSwib2Zmc2V0IjoiMTAifQAAAAESeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTc2MDEwYjJk + LWYzZTAtNDZiNS1iYmE3LTlkMWY5ODc0YTk0ZSIsInJ1bl9pZCI6InJ1bi02YmE1ZjRjNC0yZjY2 + LTRlZDMtOWIwNy0wYTczODhjMWE3YWQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJj + b250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIgaXMgYSBzb2xpZCBibGFjayJ9XX19fSwi + b2Zmc2V0IjoiMTEifQAAAAEMeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTc2MDEwYjJkLWYzZTAt + NDZiNS1iYmE3LTlkMWY5ODc0YTk0ZSIsInJ1bl9pZCI6InJ1bi02YmE1ZjRjNC0yZjY2LTRlZDMt + OWIwNy0wYTczODhjMWE3YWQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50 + IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIgc3F1YXJlIOKAlCJ9XX19fSwib2Zmc2V0IjoiMTIi + fQAAAAEFeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUi + OiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTc2MDEwYjJkLWYzZTAtNDZiNS1iYmE3LTlk + MWY5ODc0YTk0ZSIsInJ1bl9pZCI6InJ1bi02YmE1ZjRjNC0yZjY2LTRlZDMtOWIwNy0wYTczODhj + MWE3YWQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoi + dGV4dCIsInRleHQiOiIgb25lIn1dfX19LCJvZmZzZXQiOiIxMyJ9AAAAARd7InNka01lc3NhZ2Ui + OnsidHlwZSI6ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50 + X2lkIjoiYWdlbnQtNzYwMTBiMmQtZjNlMC00NmI1LWJiYTctOWQxZjk4NzRhOTRlIiwicnVuX2lk + IjoicnVuLTZiYTVmNGM0LTJmNjYtNGVkMy05YjA3LTBhNzM4OGMxYTdhZCIsIm1lc3NhZ2UiOnsi + cm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiB1bmlm + b3JtIGNvbG9yIHdpdGggbm8ifV19fX0sIm9mZnNldCI6IjE0In0AAAABCXsic2RrTWVzc2FnZSI6 + eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwiYWdlbnRf + aWQiOiJhZ2VudC03NjAxMGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5faWQi + OiJydW4tNmJhNWY0YzQtMmY2Ni00ZWQzLTliMDctMGE3Mzg4YzFhN2FkIiwibWVzc2FnZSI6eyJy + b2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiIHZpc2li + bGUifV19fX0sIm9mZnNldCI6IjE1In0AAAABDnsic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0 + YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC03NjAx + MGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5faWQiOiJydW4tNmJhNWY0YzQt + MmY2Ni00ZWQzLTliMDctMGE3Mzg4YzFhN2FkIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50 + IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiIHNoYXBlcywgdGV4dCJ9XX19fSwi + b2Zmc2V0IjoiMTYifQAAAAELeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTc2MDEwYjJkLWYzZTAt + NDZiNS1iYmE3LTlkMWY5ODc0YTk0ZSIsInJ1bl9pZCI6InJ1bi02YmE1ZjRjNC0yZjY2LTRlZDMt + OWIwNy0wYTczODhjMWE3YWQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50 + IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIsIG9yIG90aGVyIn1dfX19LCJvZmZzZXQiOiIxNyJ9 + AAAAAQh7InNka01lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQtNzYwMTBiMmQtZjNlMC00NmI1LWJiYTctOWQx + Zjk4NzRhOTRlIiwicnVuX2lkIjoicnVuLTZiYTVmNGM0LTJmNjYtNGVkMy05YjA3LTBhNzM4OGMx + YTdhZCIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0 + ZXh0IiwidGV4dCI6IiBkZXRhaWwifV19fX0sIm9mZnNldCI6IjE4In0AAAABAnsic2RrTWVzc2Fn + ZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwiYWdl + bnRfaWQiOiJhZ2VudC03NjAxMGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5f + aWQiOiJydW4tNmJhNWY0YzQtMmY2Ni00ZWQzLTliMDctMGE3Mzg4YzFhN2FkIiwibWVzc2FnZSI6 + eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiLiJ9 + XX19fSwib2Zmc2V0IjoiMTkifQAAAAEkeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsIm1l + c3NhZ2UiOnsidHlwZSI6InVzYWdlIiwiYWdlbnRfaWQiOiJhZ2VudC03NjAxMGIyZC1mM2UwLTQ2 + YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5faWQiOiJydW4tNmJhNWY0YzQtMmY2Ni00ZWQzLTli + MDctMGE3Mzg4YzFhN2FkIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExNDU2LCJvdXRwdXRUb2tl + bnMiOjcxLCJjYWNoZVJlYWRUb2tlbnMiOjg0MTYsImNhY2hlV3JpdGVUb2tlbnMiOjAsInRvdGFs + VG9rZW5zIjoxOTk0M319fSwib2Zmc2V0IjoiMjAifQAAAADKeyJzZGtNZXNzYWdlIjp7InR5cGUi + OiJzdGF0dXMiLCJtZXNzYWdlIjp7InR5cGUiOiJzdGF0dXMiLCJhZ2VudF9pZCI6ImFnZW50LTc2 + MDEwYjJkLWYzZTAtNDZiNS1iYmE3LTlkMWY5ODc0YTk0ZSIsInJ1bl9pZCI6InJ1bi02YmE1ZjRj + NC0yZjY2LTRlZDMtOWIwNy0wYTczODhjMWE3YWQiLCJzdGF0dXMiOiJGSU5JU0hFRCJ9fSwib2Zm + c2V0IjoiMjEifQAAAAJ6eyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50LTc2MDEwYjJkLWYzZTAt + NDZiNS1iYmE3LTlkMWY5ODc0YTk0ZSIsInJ1bklkIjoicnVuLTZiYTVmNGM0LTJmNjYtNGVkMy05 + YjA3LTBhNzM4OGMxYTdhZCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVE + IiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTZiYTVmNGM0LTJmNjYtNGVkMy05YjA3LTBhNzM4OGMx + YTdhZCIsImFnZW50SWQiOiJhZ2VudC03NjAxMGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5 + NGUiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6IlRo + aXMgaW1hZ2UgaXMgYSBzb2xpZCBibGFjayBzcXVhcmUg4oCUIG9uZSB1bmlmb3JtIGNvbG9yIHdp + dGggbm8gdmlzaWJsZSBzaGFwZXMsIHRleHQsIG9yIG90aGVyIGRldGFpbC4iLCJtb2RlbCI6eyJp + ZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlvbk1zIjoiNTg4NyIsImNyZWF0ZWRBdCI6IjIwMjYt + MDgtMDVUMjE6MDE6MzEuNzI1WiIsInVzYWdlIjp7ImlucHV0VG9rZW5zIjoiMTE0NTYiLCJvdXRw + dXRUb2tlbnMiOiI3MSIsImNhY2hlUmVhZFRva2VucyI6Ijg0MTYiLCJ0b3RhbFRva2VucyI6IjE5 + OTQzIn19fSwib2Zmc2V0IjoiMjIifQAAAACCeyJkb25lIjp7ImFnZW50SWQiOiJhZ2VudC03NjAx + MGIyZC1mM2UwLTQ2YjUtYmJhNy05ZDFmOTg3NGE5NGUiLCJydW5JZCI6InJ1bi02YmE1ZjRjNC0y + ZjY2LTRlZDMtOWIwNy0wYTczODhjMWE3YWQifSwib2Zmc2V0IjoiMjMifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 21:01:33 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-76010b2d-f3e0-46b5-bba7-9d1f9874a94e"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:01:37 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:01:37 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_resume_send_observe_finalizes_trace.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_resume_send_observe_finalizes_trace.yaml new file mode 100644 index 00000000..224f8419 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_resume_send_observe_finalizes_trace.yaml @@ -0,0 +1,413 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-563869da-2e13-44fc-9ee0-c328100096f0","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:00:12 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKp7ImFnZW50SWQiOiAiYWdlbnQtNTYzODY5ZGEtMmUxMy00NGZjLTllZTAtYzMyODEwMDA5 + NmYwIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgaW5p + dGlhbCB0cmFjaW5nIGNvbXBsZXRlIn0sICJvcHRpb25zIjogeyJhcGlLZXkiOiAiPFJFREFDVEVE + PiJ9fQ== + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '234' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNTYzODY5ZGEtMmUxMy00NGZjLTllZTAtYzMyODEwMDA5 + NmYwIiwicnVuX2lkIjoicnVuLTk0NzYwMjU4LWI5M2MtNDcwNC04OTUyLTIxYWFhZjNjODVkZiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADZeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC01NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4t + OTQ3NjAyNTgtYjkzYy00NzA0LTg5NTItMjFhYWFmM2M4NWRmIiwidGV4dCI6IlRoZSBleGFjdCBy + ZXNwb25zZSBpczoifX0sIm9mZnNldCI6IjIifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0 + aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC01 + NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4tOTQ3NjAy + NTgtYjkzYy00NzA0LTg5NTItMjFhYWFmM2M4NWRmIiwidGV4dCI6IiBcImN1cnNvciBpbml0aWFs + IHRyYWNpbmcifX0sIm9mZnNldCI6IjMifQAAAADOeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlu + a2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC01NjM4 + NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4tOTQ3NjAyNTgt + YjkzYy00NzA0LTg5NTItMjFhYWFmM2M4NWRmIiwidGV4dCI6IiBjb21wbGV0ZVwiIn19LCJvZmZz + ZXQiOiI0In0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7 + InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtNTYzODY5ZGEtMmUxMy00NGZjLTll + ZTAtYzMyODEwMDA5NmYwIiwicnVuX2lkIjoicnVuLTk0NzYwMjU4LWI5M2MtNDcwNC04OTUyLTIx + YWFhZjNjODVkZiIsInRleHQiOiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6M319LCJvZmZzZXQi + OiI1In0AAAABH3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0 + eXBlIjoiYXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC01NjM4NjlkYS0yZTEzLTQ0ZmMtOWVl + MC1jMzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4tOTQ3NjAyNTgtYjkzYy00NzA0LTg5NTItMjFh + YWFmM2M4NWRmIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlw + ZSI6InRleHQiLCJ0ZXh0IjoiY3Vyc29yIGluaXRpYWwgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwi + b2Zmc2V0IjoiNiJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6 + eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTU2Mzg2OWRhLTJlMTMtNDRmYy05ZWUw + LWMzMjgxMDAwOTZmMCIsInJ1bl9pZCI6InJ1bi05NDc2MDI1OC1iOTNjLTQ3MDQtODk1Mi0yMWFh + YWYzYzg1ZGYiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6Mzks + ImNhY2hlUmVhZFRva2VucyI6ODM4NCwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMi + OjE5ODAwfX19LCJvZmZzZXQiOiI3In0AAAAAyXsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVz + IiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC01NjM4NjlkYS0y + ZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4tOTQ3NjAyNTgtYjkzYy00 + NzA0LTg5NTItMjFhYWFmM2M4NWRmIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6Ijgi + fQAAAAIxeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50LTU2Mzg2OWRhLTJlMTMtNDRmYy05ZWUw + LWMzMjgxMDAwOTZmMCIsInJ1bklkIjoicnVuLTk0NzYwMjU4LWI5M2MtNDcwNC04OTUyLTIxYWFh + ZjNjODVkZiIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0 + Ijp7InJ1bklkIjoicnVuLTk0NzYwMjU4LWI5M2MtNDcwNC04OTUyLTIxYWFhZjNjODVkZiIsImFn + ZW50SWQiOiJhZ2VudC01NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJzdGF0 + dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6ImN1cnNvciBpbml0 + aWFsIHRyYWNpbmcgY29tcGxldGUiLCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJh + dGlvbk1zIjoiNDQ0NiIsImNyZWF0ZWRBdCI6IjIwMjYtMDgtMDVUMjE6MDA6MTIuOTAxWiIsInVz + YWdlIjp7ImlucHV0VG9rZW5zIjoiMTEzNzciLCJvdXRwdXRUb2tlbnMiOiIzOSIsImNhY2hlUmVh + ZFRva2VucyI6IjgzODQiLCJ0b3RhbFRva2VucyI6IjE5ODAwIn19fSwib2Zmc2V0IjoiOSJ9AAAA + AIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTU2Mzg2OWRhLTJlMTMtNDRmYy05ZWUwLWMzMjgx + MDAwOTZmMCIsInJ1bklkIjoicnVuLTk0NzYwMjU4LWI5M2MtNDcwNC04OTUyLTIxYWFhZjNjODVk + ZiJ9LCJvZmZzZXQiOiIxMCJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 21:00:14 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-563869da-2e13-44fc-9ee0-c328100096f0"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:00:17 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-563869da-2e13-44fc-9ee0-c328100096f0", "options": {"model": + {"id": "composer-2.5"}, "apiKey": "", "local": {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '334' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/ResumeAgent + response: + body: + string: '{"agentId":"agent-563869da-2e13-44fc-9ee0-c328100096f0","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:00:17 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKp7ImFnZW50SWQiOiAiYWdlbnQtNTYzODY5ZGEtMmUxMy00NGZjLTllZTAtYzMyODEwMDA5 + NmYwIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgcmVz + dW1lZCB0cmFjaW5nIGNvbXBsZXRlIn0sICJvcHRpb25zIjogeyJhcGlLZXkiOiAiPFJFREFDVEVE + PiJ9fQ== + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '234' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNTYzODY5ZGEtMmUxMy00NGZjLTllZTAtYzMyODEwMDA5 + NmYwIiwicnVuX2lkIjoicnVuLTRmYjAwYzEzLTA2NTMtNGRjYi1iMjdhLWIxOGUzZTcxNGM3MiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADZeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC01NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4t + NGZiMDBjMTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNlNzE0YzcyIiwidGV4dCI6IlRoZSB1c2VyIHJl + cXVlc3RlZCB0aGUifX0sIm9mZnNldCI6IjIifQAAAADZeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0 + aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC01 + NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4tNGZiMDBj + MTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNlNzE0YzcyIiwidGV4dCI6IiBleGFjdCBwaHJhc2UgXCJj + dXJzb3IifX0sIm9mZnNldCI6IjMifQAAAADeeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2lu + ZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC01NjM4Njlk + YS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4tNGZiMDBjMTMtMDY1 + My00ZGNiLWIyN2EtYjE4ZTNlNzE0YzcyIiwidGV4dCI6IiByZXN1bWVkIHRyYWNpbmcgY29tcGxl + dGVcIiJ9fSwib2Zmc2V0IjoiNCJ9AAAAAM97InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5n + IiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTU2Mzg2OWRh + LTJlMTMtNDRmYy05ZWUwLWMzMjgxMDAwOTZmMCIsInJ1bl9pZCI6InJ1bi00ZmIwMGMxMy0wNjUz + LTRkY2ItYjI3YS1iMThlM2U3MTRjNzIiLCJ0ZXh0IjoiIGFzIGEgcmVwbHkuIn19LCJvZmZzZXQi + OiI1In0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtNTYzODY5ZGEtMmUxMy00NGZjLTllZTAt + YzMyODEwMDA5NmYwIiwicnVuX2lkIjoicnVuLTRmYjAwYzEzLTA2NTMtNGRjYi1iMjdhLWIxOGUz + ZTcxNGM3MiIsInRleHQiOiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6Mn19LCJvZmZzZXQiOiI2 + In0AAAABBnsic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBl + IjoiYXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC01NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1j + MzI4MTAwMDk2ZjAiLCJydW5faWQiOiJydW4tNGZiMDBjMTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNl + NzE0YzcyIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6 + InRleHQiLCJ0ZXh0IjoiY3Vyc29yIn1dfX19LCJvZmZzZXQiOiI3In0AAAABGXsic2RrTWVzc2Fn + ZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwiYWdl + bnRfaWQiOiJhZ2VudC01NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5f + aWQiOiJydW4tNGZiMDBjMTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNlNzE0YzcyIiwibWVzc2FnZSI6 + eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiIHJl + c3VtZWQgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3Nh + Z2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6 + ImFnZW50LTU2Mzg2OWRhLTJlMTMtNDRmYy05ZWUwLWMzMjgxMDAwOTZmMCIsInJ1bl9pZCI6InJ1 + bi00ZmIwMGMxMy0wNjUzLTRkY2ItYjI3YS1iMThlM2U3MTRjNzIiLCJ1c2FnZSI6eyJpbnB1dFRv + a2VucyI6MTE0NjEsIm91dHB1dFRva2VucyI6MjgsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2Fj + aGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5OTA1fX19LCJvZmZzZXQiOiI5In0AAAAA + ynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVz + IiwiYWdlbnRfaWQiOiJhZ2VudC01NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAi + LCJydW5faWQiOiJydW4tNGZiMDBjMTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNlNzE0YzcyIiwic3Rh + dHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6IjEwIn0AAAACMnsicmVzdWx0Ijp7ImFnZW50SWQi + OiJhZ2VudC01NjM4NjlkYS0yZTEzLTQ0ZmMtOWVlMC1jMzI4MTAwMDk2ZjAiLCJydW5JZCI6InJ1 + bi00ZmIwMGMxMy0wNjUzLTRkY2ItYjI3YS1iMThlM2U3MTRjNzIiLCJzdGF0dXMiOiJSVU5fTElG + RUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1bi00ZmIwMGMxMy0w + NjUzLTRkY2ItYjI3YS1iMThlM2U3MTRjNzIiLCJhZ2VudElkIjoiYWdlbnQtNTYzODY5ZGEtMmUx + My00NGZjLTllZTAtYzMyODEwMDA5NmYwIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNf + RklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3IgcmVzdW1lZCB0cmFjaW5nIGNvbXBsZXRlIiwibW9k + ZWwiOnsiaWQiOiJjb21wb3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjE5OTMiLCJjcmVhdGVkQXQi + OiIyMDI2LTA4LTA1VDIxOjAwOjE3LjQ1NVoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExNDYx + Iiwib3V0cHV0VG9rZW5zIjoiMjgiLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tl + bnMiOiIxOTkwNSJ9fX0sIm9mZnNldCI6IjExIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdl + bnQtNTYzODY5ZGEtMmUxMy00NGZjLTllZTAtYzMyODEwMDA5NmYwIiwicnVuSWQiOiJydW4tNGZi + MDBjMTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNlNzE0YzcyIn0sIm9mZnNldCI6IjEyIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 21:00:17 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: "\0\0\0\05{\"runId\": \"run-4fb00c13-0653-4dcb-b27a-b18e3e714c72\"}" + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '58' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/ObserveRun + response: + body: + string: !!binary | + AAAAAjF7InJlc3VsdCI6eyJhZ2VudElkIjoiYWdlbnQtNTYzODY5ZGEtMmUxMy00NGZjLTllZTAt + YzMyODEwMDA5NmYwIiwicnVuSWQiOiJydW4tNGZiMDBjMTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNl + NzE0YzcyIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OnsicnVuSWQiOiJydW4tNGZiMDBjMTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNlNzE0YzcyIiwiYWdl + bnRJZCI6ImFnZW50LTU2Mzg2OWRhLTJlMTMtNDRmYy05ZWUwLWMzMjgxMDAwOTZmMCIsInN0YXR1 + cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0IjoiY3Vyc29yIHJlc3Vt + ZWQgdHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0 + aW9uTXMiOiIxOTkzIiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMTowMDoxNy40NTVaIiwidXNh + Z2UiOnsiaW5wdXRUb2tlbnMiOiIxMTQ2MSIsIm91dHB1dFRva2VucyI6IjI4IiwiY2FjaGVSZWFk + VG9rZW5zIjoiODQxNiIsInRvdGFsVG9rZW5zIjoiMTk5MDUifX19LCJvZmZzZXQiOiIxIn0AAAAA + gXsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtNTYzODY5ZGEtMmUxMy00NGZjLTllZTAtYzMyODEw + MDA5NmYwIiwicnVuSWQiOiJydW4tNGZiMDBjMTMtMDY1My00ZGNiLWIyN2EtYjE4ZTNlNzE0Yzcy + In0sIm9mZnNldCI6IjIifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 21:00:19 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-563869da-2e13-44fc-9ee0-c328100096f0"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:00:19 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:00:19 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_send_error_propagates_and_logs_parent_error.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_send_error_propagates_and_logs_parent_error.yaml new file mode 100644 index 00000000..646e568a --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_send_error_propagates_and_logs_parent_error.yaml @@ -0,0 +1,190 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-6cbea97e-3a6c-49bc-900e-2ec33d0bc5dd","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:02:22 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtNmNiZWE5N2UtM2E2Yy00OWJjLTkwMGUtMmVjMzNkMGJj + NWRkIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiVGhpcyByZXF1ZXN0IG11c3QgZmFpbCBiZWZvcmUg + ZXhlY3V0aW9uLiJ9LCAib3B0aW9ucyI6IHsibW9kZWwiOiB7ImlkIjogImJyYWludHJ1c3QtaW52 + YWxpZC1jdXJzb3ItbW9kZWwifSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AgAACIh7ImVycm9yIjp7ImNvZGUiOiJpbnZhbGlkX2FyZ3VtZW50IiwibWVzc2FnZSI6IkNhbm5v + dCB1c2UgdGhpcyBtb2RlbDogYnJhaW50cnVzdC1pbnZhbGlkLWN1cnNvci1tb2RlbC4gQXZhaWxh + YmxlIG1vZGVsczogZGVmYXVsdCwgZ3Jvay00LjUsIGNvbXBvc2VyLTIuNSwgY2xhdWRlLW9wdXMt + NSwgY2xhdWRlLW9wdXMtNC04LCBncHQtNS42LXNvbCwgZ3B0LTUuNSwgY2xhdWRlLWZhYmxlLTUs + IGNsYXVkZS1zb25uZXQtNSwgZ3B0LTUuNi10ZXJyYSwgY2xhdWRlLXNvbm5ldC00LTYsIGNvbXBv + c2VyLTIsIGdwdC01LjMtY29kZXgsIGNsYXVkZS1vcHVzLTQtNywgZ3B0LTUuNCwgY2xhdWRlLW9w + dXMtNC02LCBjbGF1ZGUtb3B1cy00LTUsIGdwdC01LjIsIGdwdC01LjYtbHVuYSwgZ2VtaW5pLTMu + Ni1mbGFzaCwgZ2VtaW5pLTMuMS1wcm8sIGdwdC01LjQtbWluaSwgZ3B0LTUuNC1uYW5vLCBjbGF1 + ZGUtaGFpa3UtNC01LCBjbGF1ZGUtc29ubmV0LTQtNSwgZ3B0LTUuMSwgZ2VtaW5pLTMtZmxhc2gs + IGdlbWluaS0zLjUtZmxhc2gsIGNsYXVkZS1zb25uZXQtNCwgZ3B0LTUtbWluaSwgZ2VtaW5pLTIu + NS1mbGFzaCwga2ltaS1rMywga2ltaS1rMi43LWNvZGUsIGdsbS01LjIuIFVzZSBDdXJzb3IubW9k + ZWxzLmxpc3QoKSB0byBkaXNjb3ZlciB2YWxpZCBzZWxlY3Rpb25zLiIsImRldGFpbHMiOlt7InR5 + cGUiOiJzZGsudjEuU2RrRXJyb3JEZXRhaWxzIiwiZGVidWciOnsibWVzc2FnZSI6IkNhbm5vdCB1 + c2UgdGhpcyBtb2RlbDogYnJhaW50cnVzdC1pbnZhbGlkLWN1cnNvci1tb2RlbC4gQXZhaWxhYmxl + IG1vZGVsczogZGVmYXVsdCwgZ3Jvay00LjUsIGNvbXBvc2VyLTIuNSwgY2xhdWRlLW9wdXMtNSwg + Y2xhdWRlLW9wdXMtNC04LCBncHQtNS42LXNvbCwgZ3B0LTUuNSwgY2xhdWRlLWZhYmxlLTUsIGNs + YXVkZS1zb25uZXQtNSwgZ3B0LTUuNi10ZXJyYSwgY2xhdWRlLXNvbm5ldC00LTYsIGNvbXBvc2Vy + LTIsIGdwdC01LjMtY29kZXgsIGNsYXVkZS1vcHVzLTQtNywgZ3B0LTUuNCwgY2xhdWRlLW9wdXMt + NC02LCBjbGF1ZGUtb3B1cy00LTUsIGdwdC01LjIsIGdwdC01LjYtbHVuYSwgZ2VtaW5pLTMuNi1m + bGFzaCwgZ2VtaW5pLTMuMS1wcm8sIGdwdC01LjQtbWluaSwgZ3B0LTUuNC1uYW5vLCBjbGF1ZGUt + aGFpa3UtNC01LCBjbGF1ZGUtc29ubmV0LTQtNSwgZ3B0LTUuMSwgZ2VtaW5pLTMtZmxhc2gsIGdl + bWluaS0zLjUtZmxhc2gsIGNsYXVkZS1zb25uZXQtNCwgZ3B0LTUtbWluaSwgZ2VtaW5pLTIuNS1m + bGFzaCwga2ltaS1rMywga2ltaS1rMi43LWNvZGUsIGdsbS01LjIuIFVzZSBDdXJzb3IubW9kZWxz + Lmxpc3QoKSB0byBkaXNjb3ZlciB2YWxpZCBzZWxlY3Rpb25zLiJ9LCJ2YWx1ZSI6Ikd1Y0VRMkZ1 + Ym05MElIVnpaU0IwYUdseklHMXZaR1ZzT2lCaWNtRnBiblJ5ZFhOMExXbHVkbUZzYVdRdFkzVnlj + Mjl5TFcxdlpHVnNMaUJCZG1GcGJHRmliR1VnYlc5a1pXeHpPaUJrWldaaGRXeDBMQ0JuY205ckxU + UXVOU3dnWTI5dGNHOXpaWEl0TWk0MUxDQmpiR0YxWkdVdGIzQjFjeTAxTENCamJHRjFaR1V0YjNC + MWN5MDBMVGdzSUdkd2RDMDFMall0YzI5c0xDQm5jSFF0TlM0MUxDQmpiR0YxWkdVdFptRmliR1V0 + TlN3Z1kyeGhkV1JsTFhOdmJtNWxkQzAxTENCbmNIUXROUzQyTFhSbGNuSmhMQ0JqYkdGMVpHVXRj + Mjl1Ym1WMExUUXROaXdnWTI5dGNHOXpaWEl0TWl3Z1ozQjBMVFV1TXkxamIyUmxlQ3dnWTJ4aGRX + UmxMVzl3ZFhNdE5DMDNMQ0JuY0hRdE5TNDBMQ0JqYkdGMVpHVXRiM0IxY3kwMExUWXNJR05zWVhW + a1pTMXZjSFZ6TFRRdE5Td2daM0IwTFRVdU1pd2daM0IwTFRVdU5pMXNkVzVoTENCblpXMXBibWt0 + TXk0MkxXWnNZWE5vTENCblpXMXBibWt0TXk0eExYQnlieXdnWjNCMExUVXVOQzF0YVc1cExDQm5j + SFF0TlM0MExXNWhibThzSUdOc1lYVmtaUzFvWVdscmRTMDBMVFVzSUdOc1lYVmtaUzF6YjI1dVpY + UXROQzAxTENCbmNIUXROUzR4TENCblpXMXBibWt0TXkxbWJHRnphQ3dnWjJWdGFXNXBMVE11TlMx + bWJHRnphQ3dnWTJ4aGRXUmxMWE52Ym01bGRDMDBMQ0JuY0hRdE5TMXRhVzVwTENCblpXMXBibWt0 + TWk0MUxXWnNZWE5vTENCcmFXMXBMV3N6TENCcmFXMXBMV3N5TGpjdFkyOWtaU3dnWjJ4dExUVXVN + aTRnVlhObElFTjFjbk52Y2k1dGIyUmxiSE11YkdsemRDZ3BJSFJ2SUdScGMyTnZkbVZ5SUhaaGJH + bGtJSE5sYkdWamRHbHZibk11In1dfX0= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 21:02:22 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-6cbea97e-3a6c-49bc-900e-2ec33d0bc5dd"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:02:22 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:02:22 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[events].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[events].yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[events].yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[iter_text].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[iter_text].yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[iter_text].yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[iteration].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[iteration].yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[iteration].yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[messages].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[messages].yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[messages].yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[stream].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[stream].yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[stream].yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[text].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[text].yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_consumption_paths_finalize_once[text].yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_wait_traces_cursor_owned_model_turn.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_wait_traces_cursor_owned_model_turn.yaml new file mode 100644 index 00000000..2c4ae449 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/1.0.25/test_sync_wait_traces_cursor_owned_model_turn.yaml @@ -0,0 +1,200 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:26 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFi + ZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4t + NGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwidGV4dCI6IlRoZSByZXNwb25z + ZSB3aWxsIGJlIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0 + ZjRhMDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBi + LTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgZXhhY3RseSBcImN1cnNvciB0 + cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjE0ZjRh + MDgtOGVjOS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuX2lkIjoicnVuLTRmNDIxNDBiLTdl + ODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9mZnNl + dCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRk + My1jMTM2MmQyMWJkNzMiLCJydW5faWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5 + NmM5OTNhMjYwIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNldCI6 + IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQz + LWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2 + Yzk5M2EyNjAiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEReyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJh + Z2VudF9pZCI6ImFnZW50LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1 + bl9pZCI6InJ1bi00ZjQyMTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJtZXNzYWdl + Ijp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIg + dHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAASN7InNka01lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bl9pZCI6InJ1bi00ZjQy + MTQwYi03ZTg5LTQwNDUtOTRmYy0wMDk2Yzk5M2EyNjAiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + MTEzODEsIm91dHB1dFRva2VucyI6MzcsImNhY2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0 + ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODM0fX19LCJvZmZzZXQiOiI4In0AAAAAyXsic2Rr + TWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdl + bnRfaWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2EtODRkMy1jMTM2MmQyMWJkNzMiLCJydW5f + aWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1LTk0ZmMtMDA5NmM5OTNhMjYwIiwic3RhdHVzIjoi + RklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIqeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50 + LWIxNGY0YTA4LThlYzktNDVjYS04NGQzLWMxMzYyZDIxYmQ3MyIsInJ1bklkIjoicnVuLTRmNDIx + NDBiLTdlODktNDA0NS05NGZjLTAwOTZjOTkzYTI2MCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVf + U1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTRmNDIxNDBiLTdlODktNDA0 + NS05NGZjLTAwOTZjOTkzYTI2MCIsImFnZW50SWQiOiJhZ2VudC1iMTRmNGEwOC04ZWM5LTQ1Y2Et + ODRkMy1jMTM2MmQyMWJkNzMiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hF + RCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNvbXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21w + b3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjM1ODIiLCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIw + OjI4OjI2LjI5MFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6IjExMzgxIiwib3V0cHV0VG9rZW5z + IjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2IiwidG90YWxUb2tlbnMiOiIxOTgzNCJ9fX0s + Im9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYjE0ZjRhMDgtOGVj + OS00NWNhLTg0ZDMtYzEzNjJkMjFiZDczIiwicnVuSWQiOiJydW4tNGY0MjE0MGItN2U4OS00MDQ1 + LTk0ZmMtMDA5NmM5OTNhMjYwIn0sIm9mZnNldCI6IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:28:27 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b14f4a08-8ec9-45ca-84d3-c1362d21bd73"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:28:29 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_agent_prompt_one_shot.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_agent_prompt_one_shot.yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_agent_prompt_one_shot.yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[events].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[events].yaml new file mode 100644 index 00000000..20df0945 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[events].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-63908a6f-9190-46eb-958d-f61da1c85baa","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:48 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5Zi04MDVjLThmMzFjZjdlYWRhZiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAAB/eyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIGV4YWN0bHk6In19fQAAAADZ + eyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5r + aW5nIiwiYWdlbnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODVi + YWEiLCJydW5faWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseToifX0sIm9mZnNldCI6IjMifQAAAABkeyJvZmZz + ZXQiOiI0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInRva2VucyI6NX19fQAAAAB+eyJvZmZzZXQiOiI1Iiwi + aW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5 + cGUiOiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiIgY3Vyc29yIGFzeW5jIHRyYWNpbmcifX19AAAA + ANh7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4 + NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + LCJ0ZXh0IjoiIGN1cnNvciBhc3luYyB0cmFjaW5nIn19LCJvZmZzZXQiOiI2In0AAAAAZHsib2Zm + c2V0IjoiNyIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0 + ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMiOjV9fX0AAAAAcnsib2Zmc2V0IjoiOCIs + ImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0aGlua2luZy1kZWx0YSIsInVwZGF0ZSI6eyJ0 + eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ0ZXh0IjoiIGNvbXBsZXRlIn19fQAAAADMeyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdl + bnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODViYWEiLCJydW5f + aWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwidGV4dCI6IiBj + b21wbGV0ZSJ9fSwib2Zmc2V0IjoiOSJ9AAAAAGV7Im9mZnNldCI6IjEwIiwiaW50ZXJhY3Rpb25V + cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0 + YSIsInRva2VucyI6M319fQAAAAC0eyJvZmZzZXQiOiIxMSIsInN0ZXAiOnsidHlwZSI6InRoaW5r + aW5nTWVzc2FnZSIsInN0ZXAiOnsidHlwZSI6InRoaW5raW5nTWVzc2FnZSIsIm1lc3NhZ2UiOnsi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseTogY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxl + dGUiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH97Im9mZnNldCI6IjEyIiwiaW50ZXJh + Y3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWNvbXBsZXRlZCIsInVwZGF0ZSI6eyJ0eXBl + IjoidGhpbmtpbmctY29tcGxldGVkIiwidGhpbmtpbmdEdXJhdGlvbk1zIjoxfX19AAAAAN17InNk + a01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmci + LCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIs + InJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYiLCJ0ZXh0 + IjoiIiwidGhpbmtpbmdfZHVyYXRpb25fbXMiOjF9fSwib2Zmc2V0IjoiMTMifQAAAAB/eyJvZmZz + ZXQiOiIxNCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidGV4dCI6ImN1cnNvciBhc3luYyB0cmFjaW5nIGNvbXBs + ZXRlIn19fQAAAAEeeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05 + NThkLWY2MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04 + ZjMxY2Y3ZWFkYWYiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwi + b2Zmc2V0IjoiMTUifQAAAABleyJvZmZzZXQiOiIxNiIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5 + cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMi + Ojd9fX0AAAAAiHsib2Zmc2V0IjoiMTciLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdl + Iiwic3RlcCI6eyJ0eXBlIjoiYXNzaXN0YW50TWVzc2FnZSIsIm1lc3NhZ2UiOnsidGV4dCI6ImN1 + cnNvciBhc3luYyB0cmFjaW5nIGNvbXBsZXRlIn19fX0AAAAAgXsib2Zmc2V0IjoiMTgiLCJpbnRl + cmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJ1cGRhdGUiOnsidHlwZSI6 + InN0ZXAtY29tcGxldGVkIiwic3RlcElkIjoyLCJzdGVwRHVyYXRpb25NcyI6MTQwM319fQAAAAC0 + eyJvZmZzZXQiOiIxOSIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwi + dXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExMzc3 + LCJvdXRwdXRUb2tlbnMiOjQxLCJjYWNoZVJlYWRUb2tlbnMiOjg0MTYsImNhY2hlV3JpdGVUb2tl + bnMiOjB9fX19AAAAASR7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0 + eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2 + MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3 + ZWFkYWYiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDEsImNh + Y2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5 + ODM0fX19LCJvZmZzZXQiOiIyMCJ9AAAAAMp7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIs + Im1lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5 + MC00NmViLTk1OGQtZjYxZGExYzg1YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5 + Zi04MDVjLThmMzFjZjdlYWRhZiIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiIyMSJ9 + AAAAAjB7InJlc3VsdCI6eyJhZ2VudElkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQt + ZjYxZGExYzg1YmFhIiwicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNm + N2VhZGFmIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OnsicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwiYWdl + bnRJZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIsInN0YXR1 + cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0IjoiY3Vyc29yIGFzeW5j + IHRyYWNpbmcgY29tcGxldGUiLCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlv + bk1zIjoiMzczNSIsImNyZWF0ZWRBdCI6IjIwMjYtMDgtMDVUMjA6Mjc6NDguNjY0WiIsInVzYWdl + Ijp7ImlucHV0VG9rZW5zIjoiMTEzNzciLCJvdXRwdXRUb2tlbnMiOiI0MSIsImNhY2hlUmVhZFRv + a2VucyI6Ijg0MTYiLCJ0b3RhbFRva2VucyI6IjE5ODM0In19fSwib2Zmc2V0IjoiMjIifQAAAACC + eyJkb25lIjp7ImFnZW50SWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFj + ODViYWEiLCJydW5JZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + fSwib2Zmc2V0IjoiMjMifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:27:50 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-63908a6f-9190-46eb-958d-f61da1c85baa"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[iter_text].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[iter_text].yaml new file mode 100644 index 00000000..20df0945 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[iter_text].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-63908a6f-9190-46eb-958d-f61da1c85baa","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:48 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5Zi04MDVjLThmMzFjZjdlYWRhZiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAAB/eyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIGV4YWN0bHk6In19fQAAAADZ + eyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5r + aW5nIiwiYWdlbnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODVi + YWEiLCJydW5faWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseToifX0sIm9mZnNldCI6IjMifQAAAABkeyJvZmZz + ZXQiOiI0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInRva2VucyI6NX19fQAAAAB+eyJvZmZzZXQiOiI1Iiwi + aW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5 + cGUiOiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiIgY3Vyc29yIGFzeW5jIHRyYWNpbmcifX19AAAA + ANh7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4 + NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + LCJ0ZXh0IjoiIGN1cnNvciBhc3luYyB0cmFjaW5nIn19LCJvZmZzZXQiOiI2In0AAAAAZHsib2Zm + c2V0IjoiNyIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0 + ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMiOjV9fX0AAAAAcnsib2Zmc2V0IjoiOCIs + ImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0aGlua2luZy1kZWx0YSIsInVwZGF0ZSI6eyJ0 + eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ0ZXh0IjoiIGNvbXBsZXRlIn19fQAAAADMeyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdl + bnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODViYWEiLCJydW5f + aWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwidGV4dCI6IiBj + b21wbGV0ZSJ9fSwib2Zmc2V0IjoiOSJ9AAAAAGV7Im9mZnNldCI6IjEwIiwiaW50ZXJhY3Rpb25V + cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0 + YSIsInRva2VucyI6M319fQAAAAC0eyJvZmZzZXQiOiIxMSIsInN0ZXAiOnsidHlwZSI6InRoaW5r + aW5nTWVzc2FnZSIsInN0ZXAiOnsidHlwZSI6InRoaW5raW5nTWVzc2FnZSIsIm1lc3NhZ2UiOnsi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseTogY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxl + dGUiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH97Im9mZnNldCI6IjEyIiwiaW50ZXJh + Y3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWNvbXBsZXRlZCIsInVwZGF0ZSI6eyJ0eXBl + IjoidGhpbmtpbmctY29tcGxldGVkIiwidGhpbmtpbmdEdXJhdGlvbk1zIjoxfX19AAAAAN17InNk + a01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmci + LCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIs + InJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYiLCJ0ZXh0 + IjoiIiwidGhpbmtpbmdfZHVyYXRpb25fbXMiOjF9fSwib2Zmc2V0IjoiMTMifQAAAAB/eyJvZmZz + ZXQiOiIxNCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidGV4dCI6ImN1cnNvciBhc3luYyB0cmFjaW5nIGNvbXBs + ZXRlIn19fQAAAAEeeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05 + NThkLWY2MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04 + ZjMxY2Y3ZWFkYWYiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwi + b2Zmc2V0IjoiMTUifQAAAABleyJvZmZzZXQiOiIxNiIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5 + cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMi + Ojd9fX0AAAAAiHsib2Zmc2V0IjoiMTciLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdl + Iiwic3RlcCI6eyJ0eXBlIjoiYXNzaXN0YW50TWVzc2FnZSIsIm1lc3NhZ2UiOnsidGV4dCI6ImN1 + cnNvciBhc3luYyB0cmFjaW5nIGNvbXBsZXRlIn19fX0AAAAAgXsib2Zmc2V0IjoiMTgiLCJpbnRl + cmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJ1cGRhdGUiOnsidHlwZSI6 + InN0ZXAtY29tcGxldGVkIiwic3RlcElkIjoyLCJzdGVwRHVyYXRpb25NcyI6MTQwM319fQAAAAC0 + eyJvZmZzZXQiOiIxOSIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwi + dXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExMzc3 + LCJvdXRwdXRUb2tlbnMiOjQxLCJjYWNoZVJlYWRUb2tlbnMiOjg0MTYsImNhY2hlV3JpdGVUb2tl + bnMiOjB9fX19AAAAASR7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0 + eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2 + MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3 + ZWFkYWYiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDEsImNh + Y2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5 + ODM0fX19LCJvZmZzZXQiOiIyMCJ9AAAAAMp7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIs + Im1lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5 + MC00NmViLTk1OGQtZjYxZGExYzg1YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5 + Zi04MDVjLThmMzFjZjdlYWRhZiIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiIyMSJ9 + AAAAAjB7InJlc3VsdCI6eyJhZ2VudElkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQt + ZjYxZGExYzg1YmFhIiwicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNm + N2VhZGFmIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OnsicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwiYWdl + bnRJZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIsInN0YXR1 + cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0IjoiY3Vyc29yIGFzeW5j + IHRyYWNpbmcgY29tcGxldGUiLCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlv + bk1zIjoiMzczNSIsImNyZWF0ZWRBdCI6IjIwMjYtMDgtMDVUMjA6Mjc6NDguNjY0WiIsInVzYWdl + Ijp7ImlucHV0VG9rZW5zIjoiMTEzNzciLCJvdXRwdXRUb2tlbnMiOiI0MSIsImNhY2hlUmVhZFRv + a2VucyI6Ijg0MTYiLCJ0b3RhbFRva2VucyI6IjE5ODM0In19fSwib2Zmc2V0IjoiMjIifQAAAACC + eyJkb25lIjp7ImFnZW50SWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFj + ODViYWEiLCJydW5JZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + fSwib2Zmc2V0IjoiMjMifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:27:50 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-63908a6f-9190-46eb-958d-f61da1c85baa"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[iteration].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[iteration].yaml new file mode 100644 index 00000000..20df0945 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[iteration].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-63908a6f-9190-46eb-958d-f61da1c85baa","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:48 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5Zi04MDVjLThmMzFjZjdlYWRhZiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAAB/eyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIGV4YWN0bHk6In19fQAAAADZ + eyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5r + aW5nIiwiYWdlbnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODVi + YWEiLCJydW5faWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseToifX0sIm9mZnNldCI6IjMifQAAAABkeyJvZmZz + ZXQiOiI0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInRva2VucyI6NX19fQAAAAB+eyJvZmZzZXQiOiI1Iiwi + aW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5 + cGUiOiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiIgY3Vyc29yIGFzeW5jIHRyYWNpbmcifX19AAAA + ANh7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4 + NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + LCJ0ZXh0IjoiIGN1cnNvciBhc3luYyB0cmFjaW5nIn19LCJvZmZzZXQiOiI2In0AAAAAZHsib2Zm + c2V0IjoiNyIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0 + ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMiOjV9fX0AAAAAcnsib2Zmc2V0IjoiOCIs + ImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0aGlua2luZy1kZWx0YSIsInVwZGF0ZSI6eyJ0 + eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ0ZXh0IjoiIGNvbXBsZXRlIn19fQAAAADMeyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdl + bnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODViYWEiLCJydW5f + aWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwidGV4dCI6IiBj + b21wbGV0ZSJ9fSwib2Zmc2V0IjoiOSJ9AAAAAGV7Im9mZnNldCI6IjEwIiwiaW50ZXJhY3Rpb25V + cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0 + YSIsInRva2VucyI6M319fQAAAAC0eyJvZmZzZXQiOiIxMSIsInN0ZXAiOnsidHlwZSI6InRoaW5r + aW5nTWVzc2FnZSIsInN0ZXAiOnsidHlwZSI6InRoaW5raW5nTWVzc2FnZSIsIm1lc3NhZ2UiOnsi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseTogY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxl + dGUiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH97Im9mZnNldCI6IjEyIiwiaW50ZXJh + Y3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWNvbXBsZXRlZCIsInVwZGF0ZSI6eyJ0eXBl + IjoidGhpbmtpbmctY29tcGxldGVkIiwidGhpbmtpbmdEdXJhdGlvbk1zIjoxfX19AAAAAN17InNk + a01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmci + LCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIs + InJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYiLCJ0ZXh0 + IjoiIiwidGhpbmtpbmdfZHVyYXRpb25fbXMiOjF9fSwib2Zmc2V0IjoiMTMifQAAAAB/eyJvZmZz + ZXQiOiIxNCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidGV4dCI6ImN1cnNvciBhc3luYyB0cmFjaW5nIGNvbXBs + ZXRlIn19fQAAAAEeeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05 + NThkLWY2MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04 + ZjMxY2Y3ZWFkYWYiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwi + b2Zmc2V0IjoiMTUifQAAAABleyJvZmZzZXQiOiIxNiIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5 + cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMi + Ojd9fX0AAAAAiHsib2Zmc2V0IjoiMTciLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdl + Iiwic3RlcCI6eyJ0eXBlIjoiYXNzaXN0YW50TWVzc2FnZSIsIm1lc3NhZ2UiOnsidGV4dCI6ImN1 + cnNvciBhc3luYyB0cmFjaW5nIGNvbXBsZXRlIn19fX0AAAAAgXsib2Zmc2V0IjoiMTgiLCJpbnRl + cmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJ1cGRhdGUiOnsidHlwZSI6 + InN0ZXAtY29tcGxldGVkIiwic3RlcElkIjoyLCJzdGVwRHVyYXRpb25NcyI6MTQwM319fQAAAAC0 + eyJvZmZzZXQiOiIxOSIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwi + dXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExMzc3 + LCJvdXRwdXRUb2tlbnMiOjQxLCJjYWNoZVJlYWRUb2tlbnMiOjg0MTYsImNhY2hlV3JpdGVUb2tl + bnMiOjB9fX19AAAAASR7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0 + eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2 + MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3 + ZWFkYWYiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDEsImNh + Y2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5 + ODM0fX19LCJvZmZzZXQiOiIyMCJ9AAAAAMp7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIs + Im1lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5 + MC00NmViLTk1OGQtZjYxZGExYzg1YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5 + Zi04MDVjLThmMzFjZjdlYWRhZiIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiIyMSJ9 + AAAAAjB7InJlc3VsdCI6eyJhZ2VudElkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQt + ZjYxZGExYzg1YmFhIiwicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNm + N2VhZGFmIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OnsicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwiYWdl + bnRJZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIsInN0YXR1 + cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0IjoiY3Vyc29yIGFzeW5j + IHRyYWNpbmcgY29tcGxldGUiLCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlv + bk1zIjoiMzczNSIsImNyZWF0ZWRBdCI6IjIwMjYtMDgtMDVUMjA6Mjc6NDguNjY0WiIsInVzYWdl + Ijp7ImlucHV0VG9rZW5zIjoiMTEzNzciLCJvdXRwdXRUb2tlbnMiOiI0MSIsImNhY2hlUmVhZFRv + a2VucyI6Ijg0MTYiLCJ0b3RhbFRva2VucyI6IjE5ODM0In19fSwib2Zmc2V0IjoiMjIifQAAAACC + eyJkb25lIjp7ImFnZW50SWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFj + ODViYWEiLCJydW5JZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + fSwib2Zmc2V0IjoiMjMifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:27:50 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-63908a6f-9190-46eb-958d-f61da1c85baa"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[stream].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[stream].yaml new file mode 100644 index 00000000..20df0945 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[stream].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-63908a6f-9190-46eb-958d-f61da1c85baa","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:48 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5Zi04MDVjLThmMzFjZjdlYWRhZiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAAB/eyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIGV4YWN0bHk6In19fQAAAADZ + eyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5r + aW5nIiwiYWdlbnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODVi + YWEiLCJydW5faWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseToifX0sIm9mZnNldCI6IjMifQAAAABkeyJvZmZz + ZXQiOiI0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInRva2VucyI6NX19fQAAAAB+eyJvZmZzZXQiOiI1Iiwi + aW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5 + cGUiOiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiIgY3Vyc29yIGFzeW5jIHRyYWNpbmcifX19AAAA + ANh7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4 + NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + LCJ0ZXh0IjoiIGN1cnNvciBhc3luYyB0cmFjaW5nIn19LCJvZmZzZXQiOiI2In0AAAAAZHsib2Zm + c2V0IjoiNyIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0 + ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMiOjV9fX0AAAAAcnsib2Zmc2V0IjoiOCIs + ImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0aGlua2luZy1kZWx0YSIsInVwZGF0ZSI6eyJ0 + eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ0ZXh0IjoiIGNvbXBsZXRlIn19fQAAAADMeyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdl + bnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODViYWEiLCJydW5f + aWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwidGV4dCI6IiBj + b21wbGV0ZSJ9fSwib2Zmc2V0IjoiOSJ9AAAAAGV7Im9mZnNldCI6IjEwIiwiaW50ZXJhY3Rpb25V + cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0 + YSIsInRva2VucyI6M319fQAAAAC0eyJvZmZzZXQiOiIxMSIsInN0ZXAiOnsidHlwZSI6InRoaW5r + aW5nTWVzc2FnZSIsInN0ZXAiOnsidHlwZSI6InRoaW5raW5nTWVzc2FnZSIsIm1lc3NhZ2UiOnsi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseTogY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxl + dGUiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH97Im9mZnNldCI6IjEyIiwiaW50ZXJh + Y3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWNvbXBsZXRlZCIsInVwZGF0ZSI6eyJ0eXBl + IjoidGhpbmtpbmctY29tcGxldGVkIiwidGhpbmtpbmdEdXJhdGlvbk1zIjoxfX19AAAAAN17InNk + a01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmci + LCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIs + InJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYiLCJ0ZXh0 + IjoiIiwidGhpbmtpbmdfZHVyYXRpb25fbXMiOjF9fSwib2Zmc2V0IjoiMTMifQAAAAB/eyJvZmZz + ZXQiOiIxNCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidGV4dCI6ImN1cnNvciBhc3luYyB0cmFjaW5nIGNvbXBs + ZXRlIn19fQAAAAEeeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05 + NThkLWY2MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04 + ZjMxY2Y3ZWFkYWYiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwi + b2Zmc2V0IjoiMTUifQAAAABleyJvZmZzZXQiOiIxNiIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5 + cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMi + Ojd9fX0AAAAAiHsib2Zmc2V0IjoiMTciLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdl + Iiwic3RlcCI6eyJ0eXBlIjoiYXNzaXN0YW50TWVzc2FnZSIsIm1lc3NhZ2UiOnsidGV4dCI6ImN1 + cnNvciBhc3luYyB0cmFjaW5nIGNvbXBsZXRlIn19fX0AAAAAgXsib2Zmc2V0IjoiMTgiLCJpbnRl + cmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJ1cGRhdGUiOnsidHlwZSI6 + InN0ZXAtY29tcGxldGVkIiwic3RlcElkIjoyLCJzdGVwRHVyYXRpb25NcyI6MTQwM319fQAAAAC0 + eyJvZmZzZXQiOiIxOSIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwi + dXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExMzc3 + LCJvdXRwdXRUb2tlbnMiOjQxLCJjYWNoZVJlYWRUb2tlbnMiOjg0MTYsImNhY2hlV3JpdGVUb2tl + bnMiOjB9fX19AAAAASR7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0 + eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2 + MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3 + ZWFkYWYiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDEsImNh + Y2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5 + ODM0fX19LCJvZmZzZXQiOiIyMCJ9AAAAAMp7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIs + Im1lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5 + MC00NmViLTk1OGQtZjYxZGExYzg1YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5 + Zi04MDVjLThmMzFjZjdlYWRhZiIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiIyMSJ9 + AAAAAjB7InJlc3VsdCI6eyJhZ2VudElkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQt + ZjYxZGExYzg1YmFhIiwicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNm + N2VhZGFmIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OnsicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwiYWdl + bnRJZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIsInN0YXR1 + cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0IjoiY3Vyc29yIGFzeW5j + IHRyYWNpbmcgY29tcGxldGUiLCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlv + bk1zIjoiMzczNSIsImNyZWF0ZWRBdCI6IjIwMjYtMDgtMDVUMjA6Mjc6NDguNjY0WiIsInVzYWdl + Ijp7ImlucHV0VG9rZW5zIjoiMTEzNzciLCJvdXRwdXRUb2tlbnMiOiI0MSIsImNhY2hlUmVhZFRv + a2VucyI6Ijg0MTYiLCJ0b3RhbFRva2VucyI6IjE5ODM0In19fSwib2Zmc2V0IjoiMjIifQAAAACC + eyJkb25lIjp7ImFnZW50SWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFj + ODViYWEiLCJydW5JZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + fSwib2Zmc2V0IjoiMjMifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:27:50 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-63908a6f-9190-46eb-958d-f61da1c85baa"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[text].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[text].yaml new file mode 100644 index 00000000..20df0945 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_consumption_paths_finalize_once[text].yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-63908a6f-9190-46eb-958d-f61da1c85baa","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:48 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5Zi04MDVjLThmMzFjZjdlYWRhZiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAAB/eyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIGV4YWN0bHk6In19fQAAAADZ + eyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5r + aW5nIiwiYWdlbnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODVi + YWEiLCJydW5faWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseToifX0sIm9mZnNldCI6IjMifQAAAABkeyJvZmZz + ZXQiOiI0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInRva2VucyI6NX19fQAAAAB+eyJvZmZzZXQiOiI1Iiwi + aW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5 + cGUiOiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiIgY3Vyc29yIGFzeW5jIHRyYWNpbmcifX19AAAA + ANh7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4 + NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + LCJ0ZXh0IjoiIGN1cnNvciBhc3luYyB0cmFjaW5nIn19LCJvZmZzZXQiOiI2In0AAAAAZHsib2Zm + c2V0IjoiNyIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0 + ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMiOjV9fX0AAAAAcnsib2Zmc2V0IjoiOCIs + ImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0aGlua2luZy1kZWx0YSIsInVwZGF0ZSI6eyJ0 + eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ0ZXh0IjoiIGNvbXBsZXRlIn19fQAAAADMeyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdl + bnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODViYWEiLCJydW5f + aWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwidGV4dCI6IiBj + b21wbGV0ZSJ9fSwib2Zmc2V0IjoiOSJ9AAAAAGV7Im9mZnNldCI6IjEwIiwiaW50ZXJhY3Rpb25V + cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0 + YSIsInRva2VucyI6M319fQAAAAC0eyJvZmZzZXQiOiIxMSIsInN0ZXAiOnsidHlwZSI6InRoaW5r + aW5nTWVzc2FnZSIsInN0ZXAiOnsidHlwZSI6InRoaW5raW5nTWVzc2FnZSIsIm1lc3NhZ2UiOnsi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseTogY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxl + dGUiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH97Im9mZnNldCI6IjEyIiwiaW50ZXJh + Y3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWNvbXBsZXRlZCIsInVwZGF0ZSI6eyJ0eXBl + IjoidGhpbmtpbmctY29tcGxldGVkIiwidGhpbmtpbmdEdXJhdGlvbk1zIjoxfX19AAAAAN17InNk + a01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmci + LCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIs + InJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYiLCJ0ZXh0 + IjoiIiwidGhpbmtpbmdfZHVyYXRpb25fbXMiOjF9fSwib2Zmc2V0IjoiMTMifQAAAAB/eyJvZmZz + ZXQiOiIxNCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidGV4dCI6ImN1cnNvciBhc3luYyB0cmFjaW5nIGNvbXBs + ZXRlIn19fQAAAAEeeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05 + NThkLWY2MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04 + ZjMxY2Y3ZWFkYWYiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwi + b2Zmc2V0IjoiMTUifQAAAABleyJvZmZzZXQiOiIxNiIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5 + cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMi + Ojd9fX0AAAAAiHsib2Zmc2V0IjoiMTciLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdl + Iiwic3RlcCI6eyJ0eXBlIjoiYXNzaXN0YW50TWVzc2FnZSIsIm1lc3NhZ2UiOnsidGV4dCI6ImN1 + cnNvciBhc3luYyB0cmFjaW5nIGNvbXBsZXRlIn19fX0AAAAAgXsib2Zmc2V0IjoiMTgiLCJpbnRl + cmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJ1cGRhdGUiOnsidHlwZSI6 + InN0ZXAtY29tcGxldGVkIiwic3RlcElkIjoyLCJzdGVwRHVyYXRpb25NcyI6MTQwM319fQAAAAC0 + eyJvZmZzZXQiOiIxOSIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwi + dXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExMzc3 + LCJvdXRwdXRUb2tlbnMiOjQxLCJjYWNoZVJlYWRUb2tlbnMiOjg0MTYsImNhY2hlV3JpdGVUb2tl + bnMiOjB9fX19AAAAASR7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0 + eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2 + MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3 + ZWFkYWYiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDEsImNh + Y2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5 + ODM0fX19LCJvZmZzZXQiOiIyMCJ9AAAAAMp7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIs + Im1lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5 + MC00NmViLTk1OGQtZjYxZGExYzg1YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5 + Zi04MDVjLThmMzFjZjdlYWRhZiIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiIyMSJ9 + AAAAAjB7InJlc3VsdCI6eyJhZ2VudElkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQt + ZjYxZGExYzg1YmFhIiwicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNm + N2VhZGFmIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OnsicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwiYWdl + bnRJZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIsInN0YXR1 + cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0IjoiY3Vyc29yIGFzeW5j + IHRyYWNpbmcgY29tcGxldGUiLCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlv + bk1zIjoiMzczNSIsImNyZWF0ZWRBdCI6IjIwMjYtMDgtMDVUMjA6Mjc6NDguNjY0WiIsInVzYWdl + Ijp7ImlucHV0VG9rZW5zIjoiMTEzNzciLCJvdXRwdXRUb2tlbnMiOiI0MSIsImNhY2hlUmVhZFRv + a2VucyI6Ijg0MTYiLCJ0b3RhbFRva2VucyI6IjE5ODM0In19fSwib2Zmc2V0IjoiMjIifQAAAACC + eyJkb25lIjp7ImFnZW50SWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFj + ODViYWEiLCJydW5JZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + fSwib2Zmc2V0IjoiMjMifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:27:50 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-63908a6f-9190-46eb-958d-f61da1c85baa"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_messages_preserve_callbacks_and_trace.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_messages_preserve_callbacks_and_trace.yaml new file mode 100644 index 00000000..20df0945 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_async_messages_preserve_callbacks_and_trace.yaml @@ -0,0 +1,227 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-63908a6f-9190-46eb-958d-f61da1c85baa","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:48 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgYXN5 + bmMgdHJhY2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiZW5hYmxlRGVsdGFzIjogdHJ1ZSwg + ImVuYWJsZVN0ZXBzIjogdHJ1ZSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQtZjYxZGExYzg1 + YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5Zi04MDVjLThmMzFjZjdlYWRhZiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAAB/eyJvZmZzZXQiOiIyIiwiaW50 + ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5cGUi + OiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiJSZXBseWluZyB3aXRoIGV4YWN0bHk6In19fQAAAADZ + eyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5r + aW5nIiwiYWdlbnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODVi + YWEiLCJydW5faWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseToifX0sIm9mZnNldCI6IjMifQAAAABkeyJvZmZz + ZXQiOiI0IiwiaW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInRva2VucyI6NX19fQAAAAB+eyJvZmZzZXQiOiI1Iiwi + aW50ZXJhY3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWRlbHRhIiwidXBkYXRlIjp7InR5 + cGUiOiJ0aGlua2luZy1kZWx0YSIsInRleHQiOiIgY3Vyc29yIGFzeW5jIHRyYWNpbmcifX19AAAA + ANh7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4 + NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + LCJ0ZXh0IjoiIGN1cnNvciBhc3luYyB0cmFjaW5nIn19LCJvZmZzZXQiOiI2In0AAAAAZHsib2Zm + c2V0IjoiNyIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0 + ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMiOjV9fX0AAAAAcnsib2Zmc2V0IjoiOCIs + ImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0aGlua2luZy1kZWx0YSIsInVwZGF0ZSI6eyJ0 + eXBlIjoidGhpbmtpbmctZGVsdGEiLCJ0ZXh0IjoiIGNvbXBsZXRlIn19fQAAAADMeyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdl + bnRfaWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFjODViYWEiLCJydW5f + aWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwidGV4dCI6IiBj + b21wbGV0ZSJ9fSwib2Zmc2V0IjoiOSJ9AAAAAGV7Im9mZnNldCI6IjEwIiwiaW50ZXJhY3Rpb25V + cGRhdGUiOnsidHlwZSI6InRva2VuLWRlbHRhIiwidXBkYXRlIjp7InR5cGUiOiJ0b2tlbi1kZWx0 + YSIsInRva2VucyI6M319fQAAAAC0eyJvZmZzZXQiOiIxMSIsInN0ZXAiOnsidHlwZSI6InRoaW5r + aW5nTWVzc2FnZSIsInN0ZXAiOnsidHlwZSI6InRoaW5raW5nTWVzc2FnZSIsIm1lc3NhZ2UiOnsi + dGV4dCI6IlJlcGx5aW5nIHdpdGggZXhhY3RseTogY3Vyc29yIGFzeW5jIHRyYWNpbmcgY29tcGxl + dGUiLCJ0aGlua2luZ0R1cmF0aW9uTXMiOjF9fX19AAAAAH97Im9mZnNldCI6IjEyIiwiaW50ZXJh + Y3Rpb25VcGRhdGUiOnsidHlwZSI6InRoaW5raW5nLWNvbXBsZXRlZCIsInVwZGF0ZSI6eyJ0eXBl + IjoidGhpbmtpbmctY29tcGxldGVkIiwidGhpbmtpbmdEdXJhdGlvbk1zIjoxfX19AAAAAN17InNk + a01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmci + LCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIs + InJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYiLCJ0ZXh0 + IjoiIiwidGhpbmtpbmdfZHVyYXRpb25fbXMiOjF9fSwib2Zmc2V0IjoiMTMifQAAAAB/eyJvZmZz + ZXQiOiIxNCIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidXBkYXRl + Ijp7InR5cGUiOiJ0ZXh0LWRlbHRhIiwidGV4dCI6ImN1cnNvciBhc3luYyB0cmFjaW5nIGNvbXBs + ZXRlIn19fQAAAAEeeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05 + NThkLWY2MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04 + ZjMxY2Y3ZWFkYWYiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IgYXN5bmMgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwi + b2Zmc2V0IjoiMTUifQAAAABleyJvZmZzZXQiOiIxNiIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5 + cGUiOiJ0b2tlbi1kZWx0YSIsInVwZGF0ZSI6eyJ0eXBlIjoidG9rZW4tZGVsdGEiLCJ0b2tlbnMi + Ojd9fX0AAAAAiHsib2Zmc2V0IjoiMTciLCJzdGVwIjp7InR5cGUiOiJhc3Npc3RhbnRNZXNzYWdl + Iiwic3RlcCI6eyJ0eXBlIjoiYXNzaXN0YW50TWVzc2FnZSIsIm1lc3NhZ2UiOnsidGV4dCI6ImN1 + cnNvciBhc3luYyB0cmFjaW5nIGNvbXBsZXRlIn19fX0AAAAAgXsib2Zmc2V0IjoiMTgiLCJpbnRl + cmFjdGlvblVwZGF0ZSI6eyJ0eXBlIjoic3RlcC1jb21wbGV0ZWQiLCJ1cGRhdGUiOnsidHlwZSI6 + InN0ZXAtY29tcGxldGVkIiwic3RlcElkIjoyLCJzdGVwRHVyYXRpb25NcyI6MTQwM319fQAAAAC0 + eyJvZmZzZXQiOiIxOSIsImludGVyYWN0aW9uVXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwi + dXBkYXRlIjp7InR5cGUiOiJ0dXJuLWVuZGVkIiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExMzc3 + LCJvdXRwdXRUb2tlbnMiOjQxLCJjYWNoZVJlYWRUb2tlbnMiOjg0MTYsImNhY2hlV3JpdGVUb2tl + bnMiOjB9fX19AAAAASR7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0 + eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2 + MWRhMWM4NWJhYSIsInJ1bl9pZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3 + ZWFkYWYiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDEsImNh + Y2hlUmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5 + ODM0fX19LCJvZmZzZXQiOiIyMCJ9AAAAAMp7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIs + Im1lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNjM5MDhhNmYtOTE5 + MC00NmViLTk1OGQtZjYxZGExYzg1YmFhIiwicnVuX2lkIjoicnVuLWZkNGMxYTlkLTI4NDctNDQ5 + Zi04MDVjLThmMzFjZjdlYWRhZiIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiIyMSJ9 + AAAAAjB7InJlc3VsdCI6eyJhZ2VudElkIjoiYWdlbnQtNjM5MDhhNmYtOTE5MC00NmViLTk1OGQt + ZjYxZGExYzg1YmFhIiwicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNm + N2VhZGFmIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OnsicnVuSWQiOiJydW4tZmQ0YzFhOWQtMjg0Ny00NDlmLTgwNWMtOGYzMWNmN2VhZGFmIiwiYWdl + bnRJZCI6ImFnZW50LTYzOTA4YTZmLTkxOTAtNDZlYi05NThkLWY2MWRhMWM4NWJhYSIsInN0YXR1 + cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0IjoiY3Vyc29yIGFzeW5j + IHRyYWNpbmcgY29tcGxldGUiLCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlv + bk1zIjoiMzczNSIsImNyZWF0ZWRBdCI6IjIwMjYtMDgtMDVUMjA6Mjc6NDguNjY0WiIsInVzYWdl + Ijp7ImlucHV0VG9rZW5zIjoiMTEzNzciLCJvdXRwdXRUb2tlbnMiOiI0MSIsImNhY2hlUmVhZFRv + a2VucyI6Ijg0MTYiLCJ0b3RhbFRva2VucyI6IjE5ODM0In19fSwib2Zmc2V0IjoiMjIifQAAAACC + eyJkb25lIjp7ImFnZW50SWQiOiJhZ2VudC02MzkwOGE2Zi05MTkwLTQ2ZWItOTU4ZC1mNjFkYTFj + ODViYWEiLCJydW5JZCI6InJ1bi1mZDRjMWE5ZC0yODQ3LTQ0OWYtODA1Yy04ZjMxY2Y3ZWFkYWYi + fSwib2Zmc2V0IjoiMjMifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:27:50 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-63908a6f-9190-46eb-958d-f61da1c85baa"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:52 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_auto_cursor_sdk.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_auto_cursor_sdk.yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_auto_cursor_sdk.yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_builtin_tool_events_create_one_tool_span.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_builtin_tool_events_create_one_tool_span.yaml new file mode 100644 index 00000000..66987145 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_builtin_tool_events_create_one_tool_span.yaml @@ -0,0 +1,237 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-4affb328-a331-4735-a10b-4e6bea16cfa6","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:53 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAMt7ImFnZW50SWQiOiAiYWdlbnQtNGFmZmIzMjgtYTMzMS00NzM1LWExMGItNGU2YmVhMTZj + ZmE2IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiVXNlIHRoZSBzaGVsbCB0b29sIHRvIHJ1biBgcHJp + bnRmIGN1cnNvci10b29sLWNvbXBsZXRlYCwgdGhlbiByZXBseSB3aXRoIHRoZSBvdXRwdXQuIn0s + ICJvcHRpb25zIjogeyJhcGlLZXkiOiAiPFJFREFDVEVEPiJ9fQ== + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '267' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtNGFmZmIzMjgtYTMzMS00NzM1LWExMGItNGU2YmVhMTZj + ZmE2IiwicnVuX2lkIjoicnVuLTQ3MDk5ZGIwLWM2MmEtNDkyMS1hMzY0LWM0YzVkNmExNmIxMyIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADoeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC00YWZmYjMyOC1hMzMxLTQ3MzUtYTEwYi00ZTZiZWExNmNmYTYiLCJydW5faWQiOiJydW4t + NDcwOTlkYjAtYzYyYS00OTIxLWEzNjQtYzRjNWQ2YTE2YjEzIiwidGV4dCI6IlJ1bm5pbmcgYHBy + aW50ZiBjdXJzb3ItdG9vbC1jb21wbGV0ZWAifX0sIm9mZnNldCI6IjIifQAAAADXeyJzZGtNZXNz + YWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdl + bnRfaWQiOiJhZ2VudC00YWZmYjMyOC1hMzMxLTQ3MzUtYTEwYi00ZTZiZWExNmNmYTYiLCJydW5f + aWQiOiJydW4tNDcwOTlkYjAtYzYyYS00OTIxLWEzNjQtYzRjNWQ2YTE2YjEzIiwidGV4dCI6IiBh + bmQgd2lsbCByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0 + eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoi + YWdlbnQtNGFmZmIzMjgtYTMzMS00NzM1LWExMGItNGU2YmVhMTZjZmE2IiwicnVuX2lkIjoicnVu + LTQ3MDk5ZGIwLWM2MmEtNDkyMS1hMzY0LWM0YzVkNmExNmIxMyIsInRleHQiOiIgdGhlIG91dHB1 + dC4ifX0sIm9mZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIs + Im1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC00YWZmYjMyOC1h + MzMxLTQ3MzUtYTEwYi00ZTZiZWExNmNmYTYiLCJydW5faWQiOiJydW4tNDcwOTlkYjAtYzYyYS00 + OTIxLWEzNjQtYzRjNWQ2YTE2YjEzIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjox + fX0sIm9mZnNldCI6IjUifQAAAAFTeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0b29sX2NhbGwiLCJt + ZXNzYWdlIjp7InR5cGUiOiJ0b29sX2NhbGwiLCJhZ2VudF9pZCI6ImFnZW50LTRhZmZiMzI4LWEz + MzEtNDczNS1hMTBiLTRlNmJlYTE2Y2ZhNiIsInJ1bl9pZCI6InJ1bi00NzA5OWRiMC1jNjJhLTQ5 + MjEtYTM2NC1jNGM1ZDZhMTZiMTMiLCJjYWxsX2lkIjoidG9vbF80MjM3MTEzNC04ZGJhLTQ0MWMt + ODQ3OS03OWVlN2RkZWFkOSIsIm5hbWUiOiJzaGVsbCIsInN0YXR1cyI6InJ1bm5pbmciLCJhcmdz + Ijp7ImNvbW1hbmQiOiJwcmludGYgY3Vyc29yLXRvb2wtY29tcGxldGUiLCJ0aW1lb3V0IjozMDAw + MH19fSwib2Zmc2V0IjoiNiJ9AAAAAdd7InNka01lc3NhZ2UiOnsidHlwZSI6InRvb2xfY2FsbCIs + Im1lc3NhZ2UiOnsidHlwZSI6InRvb2xfY2FsbCIsImFnZW50X2lkIjoiYWdlbnQtNGFmZmIzMjgt + YTMzMS00NzM1LWExMGItNGU2YmVhMTZjZmE2IiwicnVuX2lkIjoicnVuLTQ3MDk5ZGIwLWM2MmEt + NDkyMS1hMzY0LWM0YzVkNmExNmIxMyIsImNhbGxfaWQiOiJ0b29sXzQyMzcxMTM0LThkYmEtNDQx + Yy04NDc5LTc5ZWU3ZGRlYWQ5IiwibmFtZSI6InNoZWxsIiwic3RhdHVzIjoiY29tcGxldGVkIiwi + YXJncyI6eyJjb21tYW5kIjoicHJpbnRmIGN1cnNvci10b29sLWNvbXBsZXRlIiwidGltZW91dCI6 + MzAwMDB9LCJyZXN1bHQiOnsic3RhdHVzIjoic3VjY2VzcyIsInZhbHVlIjp7ImV4aXRDb2RlIjow + LCJzaWduYWwiOiIiLCJzdGRvdXQiOiJjdXJzb3ItdG9vbC1jb21wbGV0ZSIsInN0ZGVyciI6IiIs + ImV4ZWN1dGlvblRpbWUiOjE1NDl9fX19LCJvZmZzZXQiOiI3In0AAAAA2Hsic2RrTWVzc2FnZSI6 + eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lk + IjoiYWdlbnQtNGFmZmIzMjgtYTMzMS00NzM1LWExMGItNGU2YmVhMTZjZmE2IiwicnVuX2lkIjoi + cnVuLTQ3MDk5ZGIwLWM2MmEtNDkyMS1hMzY0LWM0YzVkNmExNmIxMyIsInRleHQiOiJUaGUgY29t + bWFuZCBjb21wbGV0ZWQifX0sIm9mZnNldCI6IjgifQAAAADdeyJzZGtNZXNzYWdlIjp7InR5cGUi + OiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2Vu + dC00YWZmYjMyOC1hMzMxLTQ3MzUtYTEwYi00ZTZiZWExNmNmYTYiLCJydW5faWQiOiJydW4tNDcw + OTlkYjAtYzYyYS00OTIxLWEzNjQtYzRjNWQ2YTE2YjEzIiwidGV4dCI6IiBzdWNjZXNzZnVsbHkg + YW5kIHJldHVybmVkIn19LCJvZmZzZXQiOiI5In0AAAAA3nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + NGFmZmIzMjgtYTMzMS00NzM1LWExMGItNGU2YmVhMTZjZmE2IiwicnVuX2lkIjoicnVuLTQ3MDk5 + ZGIwLWM2MmEtNDkyMS1hMzY0LWM0YzVkNmExNmIxMyIsInRleHQiOiIgXCJjdXJzb3ItdG9vbC1j + b21wbGV0ZVwiLiJ9fSwib2Zmc2V0IjoiMTAifQAAAADfeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0 + aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC00 + YWZmYjMyOC1hMzMxLTQ3MzUtYTEwYi00ZTZiZWExNmNmYTYiLCJydW5faWQiOiJydW4tNDcwOTlk + YjAtYzYyYS00OTIxLWEzNjQtYzRjNWQ2YTE2YjEzIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0 + aW9uX21zIjo0MTh9fSwib2Zmc2V0IjoiMTEifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJh + c3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50 + LTRhZmZiMzI4LWEzMzEtNDczNS1hMTBiLTRlNmJlYTE2Y2ZhNiIsInJ1bl9pZCI6InJ1bi00NzA5 + OWRiMC1jNjJhLTQ5MjEtYTM2NC1jNGM1ZDZhMTZiMTMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Np + c3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiJgYGBcbiJ9XX19fSwib2Zm + c2V0IjoiMTIifQAAAAEXeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdl + Ijp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTRhZmZiMzI4LWEzMzEtNDcz + NS1hMTBiLTRlNmJlYTE2Y2ZhNiIsInJ1bl9pZCI6InJ1bi00NzA5OWRiMC1jNjJhLTQ5MjEtYTM2 + NC1jNGM1ZDZhMTZiMTMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50Ijpb + eyJ0eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3ItdG9vbC1jb21wbGV0ZVxuIn1dfX19LCJvZmZz + ZXQiOiIxMyJ9AAAAAQR7InNka01lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsIm1lc3NhZ2Ui + OnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQtNGFmZmIzMjgtYTMzMS00NzM1 + LWExMGItNGU2YmVhMTZjZmE2IiwicnVuX2lkIjoicnVuLTQ3MDk5ZGIwLWM2MmEtNDkyMS1hMzY0 + LWM0YzVkNmExNmIxMyIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7 + InR5cGUiOiJ0ZXh0IiwidGV4dCI6ImBgYCJ9XX19fSwib2Zmc2V0IjoiMTQifQAAAAEleyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsIm1lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwiYWdlbnRf + aWQiOiJhZ2VudC00YWZmYjMyOC1hMzMxLTQ3MzUtYTEwYi00ZTZiZWExNmNmYTYiLCJydW5faWQi + OiJydW4tNDcwOTlkYjAtYzYyYS00OTIxLWEzNjQtYzRjNWQ2YTE2YjEzIiwidXNhZ2UiOnsiaW5w + dXRUb2tlbnMiOjIyODc5LCJvdXRwdXRUb2tlbnMiOjk1LCJjYWNoZVJlYWRUb2tlbnMiOjE2ODAw + LCJjYWNoZVdyaXRlVG9rZW5zIjowLCJ0b3RhbFRva2VucyI6Mzk3NzR9fX0sIm9mZnNldCI6IjE1 + In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoi + c3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC00YWZmYjMyOC1hMzMxLTQ3MzUtYTEwYi00ZTZiZWEx + NmNmYTYiLCJydW5faWQiOiJydW4tNDcwOTlkYjAtYzYyYS00OTIxLWEzNjQtYzRjNWQ2YTE2YjEz + Iiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6IjE2In0AAAACMnsicmVzdWx0Ijp7ImFn + ZW50SWQiOiJhZ2VudC00YWZmYjMyOC1hMzMxLTQ3MzUtYTEwYi00ZTZiZWExNmNmYTYiLCJydW5J + ZCI6InJ1bi00NzA5OWRiMC1jNjJhLTQ5MjEtYTM2NC1jNGM1ZDZhMTZiMTMiLCJzdGF0dXMiOiJS + VU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1bi00NzA5 + OWRiMC1jNjJhLTQ5MjEtYTM2NC1jNGM1ZDZhMTZiMTMiLCJhZ2VudElkIjoiYWdlbnQtNGFmZmIz + MjgtYTMzMS00NzM1LWExMGItNGU2YmVhMTZjZmE2Iiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9T + VEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJgYGBcbmN1cnNvci10b29sLWNvbXBsZXRlXG5gYGAi + LCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlvbk1zIjoiNTQzMSIsImNyZWF0 + ZWRBdCI6IjIwMjYtMDgtMDVUMjA6Mjc6NTMuNjczWiIsInVzYWdlIjp7ImlucHV0VG9rZW5zIjoi + MjI4NzkiLCJvdXRwdXRUb2tlbnMiOiI5NSIsImNhY2hlUmVhZFRva2VucyI6IjE2ODAwIiwidG90 + YWxUb2tlbnMiOiIzOTc3NCJ9fX0sIm9mZnNldCI6IjE3In0AAAAAgnsiZG9uZSI6eyJhZ2VudElk + IjoiYWdlbnQtNGFmZmIzMjgtYTMzMS00NzM1LWExMGItNGU2YmVhMTZjZmE2IiwicnVuSWQiOiJy + dW4tNDcwOTlkYjAtYzYyYS00OTIxLWEzNjQtYzRjNWQ2YTE2YjEzIn0sIm9mZnNldCI6IjE4In0C + AAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:27:55 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-4affb328-a331-4735-a10b-4e6bea16cfa6"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:59 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:27:59 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_characterize_no_downstream_provider_spans.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_characterize_no_downstream_provider_spans.yaml new file mode 100644 index 00000000..d107643a --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_characterize_no_downstream_provider_spans.yaml @@ -0,0 +1,201 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8572b9da-ef9a-4487-bb21-e2ac495764b0","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:25:24 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKt7ImFnZW50SWQiOiAiYWdlbnQtODU3MmI5ZGEtZWY5YS00NDg3LWJiMjEtZTJhYzQ5NTc2 + NGIwIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgY2hh + cmFjdGVyaXphdGlvbiBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RF + RD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '235' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtODU3MmI5ZGEtZWY5YS00NDg3LWJiMjEtZTJhYzQ5NTc2 + NGIwIiwicnVuX2lkIjoicnVuLTg0MDYwYWJjLWI0Y2MtNDM3Mi04MmI2LTRhYWJlMDAzYTc3NyIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADXeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04NTcyYjlkYS1lZjlhLTQ0ODctYmIyMS1lMmFjNDk1NzY0YjAiLCJydW5faWQiOiJydW4t + ODQwNjBhYmMtYjRjYy00MzcyLTgyYjYtNGFhYmUwMDNhNzc3IiwidGV4dCI6IlRoZSB1c2VyIHJl + cXVlc3RlZCBhIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtODU3 + MmI5ZGEtZWY5YS00NDg3LWJiMjEtZTJhYzQ5NTc2NGIwIiwicnVuX2lkIjoicnVuLTg0MDYwYWJj + LWI0Y2MtNDM3Mi04MmI2LTRhYWJlMDAzYTc3NyIsInRleHQiOiIgcmVwbHkgY29udGFpbmluZyBl + eGFjdGx5In19LCJvZmZzZXQiOiIzIn0AAAAA3Xsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtp + bmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtODU3MmI5 + ZGEtZWY5YS00NDg3LWJiMjEtZTJhYzQ5NTc2NGIwIiwicnVuX2lkIjoicnVuLTg0MDYwYWJjLWI0 + Y2MtNDM3Mi04MmI2LTRhYWJlMDAzYTc3NyIsInRleHQiOiIgXCJjdXJzb3IgY2hhcmFjdGVyaXph + dGlvbiJ9fSwib2Zmc2V0IjoiNCJ9AAAAAM97InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5n + IiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTg1NzJiOWRh + LWVmOWEtNDQ4Ny1iYjIxLWUyYWM0OTU3NjRiMCIsInJ1bl9pZCI6InJ1bi04NDA2MGFiYy1iNGNj + LTQzNzItODJiNi00YWFiZTAwM2E3NzciLCJ0ZXh0IjoiIGNvbXBsZXRlXCIuIn19LCJvZmZzZXQi + OiI1In0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJtZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtODU3MmI5ZGEtZWY5YS00NDg3LWJiMjEt + ZTJhYzQ5NTc2NGIwIiwicnVuX2lkIjoicnVuLTg0MDYwYWJjLWI0Y2MtNDM3Mi04MmI2LTRhYWJl + MDAzYTc3NyIsInRleHQiOiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6MX19LCJvZmZzZXQiOiI2 + In0AAAABIHsic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBl + IjoiYXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC04NTcyYjlkYS1lZjlhLTQ0ODctYmIyMS1l + MmFjNDk1NzY0YjAiLCJydW5faWQiOiJydW4tODQwNjBhYmMtYjRjYy00MzcyLTgyYjYtNGFhYmUw + MDNhNzc3IiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6 + InRleHQiLCJ0ZXh0IjoiY3Vyc29yIGNoYXJhY3Rlcml6YXRpb24gY29tcGxldGUifV19fX0sIm9m + ZnNldCI6IjcifQAAAAEjeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsIm1lc3NhZ2UiOnsi + dHlwZSI6InVzYWdlIiwiYWdlbnRfaWQiOiJhZ2VudC04NTcyYjlkYS1lZjlhLTQ0ODctYmIyMS1l + MmFjNDk1NzY0YjAiLCJydW5faWQiOiJydW4tODQwNjBhYmMtYjRjYy00MzcyLTgyYjYtNGFhYmUw + MDNhNzc3IiwidXNhZ2UiOnsiaW5wdXRUb2tlbnMiOjExMzc3LCJvdXRwdXRUb2tlbnMiOjM2LCJj + YWNoZVJlYWRUb2tlbnMiOjgzODQsImNhY2hlV3JpdGVUb2tlbnMiOjAsInRvdGFsVG9rZW5zIjox + OTc5N319fSwib2Zmc2V0IjoiOCJ9AAAAAMl7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIs + Im1lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtODU3MmI5ZGEtZWY5 + YS00NDg3LWJiMjEtZTJhYzQ5NTc2NGIwIiwicnVuX2lkIjoicnVuLTg0MDYwYWJjLWI0Y2MtNDM3 + Mi04MmI2LTRhYWJlMDAzYTc3NyIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiI5In0A + AAACM3sicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04NTcyYjlkYS1lZjlhLTQ0ODctYmIyMS1l + MmFjNDk1NzY0YjAiLCJydW5JZCI6InJ1bi04NDA2MGFiYy1iNGNjLTQzNzItODJiNi00YWFiZTAw + M2E3NzciLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6 + eyJydW5JZCI6InJ1bi04NDA2MGFiYy1iNGNjLTQzNzItODJiNi00YWFiZTAwM2E3NzciLCJhZ2Vu + dElkIjoiYWdlbnQtODU3MmI5ZGEtZWY5YS00NDg3LWJiMjEtZTJhYzQ5NTc2NGIwIiwic3RhdHVz + IjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3IgY2hhcmFj + dGVyaXphdGlvbiBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0 + aW9uTXMiOiIzMDg2IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNToyNC43NzVaIiwidXNh + Z2UiOnsiaW5wdXRUb2tlbnMiOiIxMTM3NyIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFk + VG9rZW5zIjoiODM4NCIsInRvdGFsVG9rZW5zIjoiMTk3OTcifX19LCJvZmZzZXQiOiIxMCJ9AAAA + AIJ7ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LTg1NzJiOWRhLWVmOWEtNDQ4Ny1iYjIxLWUyYWM0 + OTU3NjRiMCIsInJ1bklkIjoicnVuLTg0MDYwYWJjLWI0Y2MtNDM3Mi04MmI2LTRhYWJlMDAzYTc3 + NyJ9LCJvZmZzZXQiOiIxMSJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:25:26 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8572b9da-ef9a-4487-bb21-e2ac495764b0"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:25:28 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:25:28 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_custom_tool_dispatch_traces_under_the_agents_run.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_custom_tool_dispatch_traces_under_the_agents_run.yaml new file mode 100644 index 00000000..f90e8a74 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_custom_tool_dispatch_traces_under_the_agents_run.yaml @@ -0,0 +1,302 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-b27caf3c-b7dd-4fb7-9b3b-1dd496f243b8","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Thu, 06 Aug 2026 15:25:07 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtYjI3Y2FmM2MtYjdkZC00ZmI3LTliM2ItMWRkNDk2ZjI0 + M2I4IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYjI3Y2FmM2MtYjdkZC00ZmI3LTliM2ItMWRkNDk2ZjI0 + M2I4IiwicnVuX2lkIjoicnVuLTU2NDMyYWMwLTdjNGQtNGMwZS1hNjFlLWIyMGVmZjdiZTlkMyIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1iMjdjYWYzYy1iN2RkLTRmYjctOWIzYi0xZGQ0OTZmMjQzYjgiLCJydW5faWQiOiJydW4t + NTY0MzJhYzAtN2M0ZC00YzBlLWE2MWUtYjIwZWZmN2JlOWQzIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + YjI3Y2FmM2MtYjdkZC00ZmI3LTliM2ItMWRkNDk2ZjI0M2I4IiwicnVuX2lkIjoicnVuLTU2NDMy + YWMwLTdjNGQtNGMwZS1hNjFlLWIyMGVmZjdiZTlkMyIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYjI3 + Y2FmM2MtYjdkZC00ZmI3LTliM2ItMWRkNDk2ZjI0M2I4IiwicnVuX2lkIjoicnVuLTU2NDMyYWMw + LTdjNGQtNGMwZS1hNjFlLWIyMGVmZjdiZTlkMyIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC1iMjdjYWYzYy1iN2RkLTRmYjct + OWIzYi0xZGQ0OTZmMjQzYjgiLCJydW5faWQiOiJydW4tNTY0MzJhYzAtN2M0ZC00YzBlLWE2MWUt + YjIwZWZmN2JlOWQzIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEXeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LWIyN2NhZjNjLWI3ZGQtNGZiNy05 + YjNiLTFkZDQ5NmYyNDNiOCIsInJ1bl9pZCI6InJ1bi01NjQzMmFjMC03YzRkLTRjMGUtYTYxZS1i + MjBlZmY3YmU5ZDMiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0 + IjoiNiJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBl + IjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LWIyN2NhZjNjLWI3ZGQtNGZiNy05YjNiLTFkZDQ5 + NmYyNDNiOCIsInJ1bl9pZCI6InJ1bi01NjQzMmFjMC03YzRkLTRjMGUtYTYxZS1iMjBlZmY3YmU5 + ZDMiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzOTIsIm91dHB1dFRva2VucyI6MzcsImNhY2hl + UmVhZFRva2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODQ1 + fX19LCJvZmZzZXQiOiI3In0AAAAAyXsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVz + c2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC1iMjdjYWYzYy1iN2RkLTRm + YjctOWIzYi0xZGQ0OTZmMjQzYjgiLCJydW5faWQiOiJydW4tNTY0MzJhYzAtN2M0ZC00YzBlLWE2 + MWUtYjIwZWZmN2JlOWQzIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6IjgifQAAAAIp + eyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50LWIyN2NhZjNjLWI3ZGQtNGZiNy05YjNiLTFkZDQ5 + NmYyNDNiOCIsInJ1bklkIjoicnVuLTU2NDMyYWMwLTdjNGQtNGMwZS1hNjFlLWIyMGVmZjdiZTlk + MyIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1 + bklkIjoicnVuLTU2NDMyYWMwLTdjNGQtNGMwZS1hNjFlLWIyMGVmZjdiZTlkMyIsImFnZW50SWQi + OiJhZ2VudC1iMjdjYWYzYy1iN2RkLTRmYjctOWIzYi0xZGQ0OTZmMjQzYjgiLCJzdGF0dXMiOiJS + VU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6ImN1cnNvciB0cmFjaW5nIGNv + bXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21wb3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjMxNjci + LCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA2VDE1OjI1OjA3LjE3MloiLCJ1c2FnZSI6eyJpbnB1dFRv + a2VucyI6IjExMzkyIiwib3V0cHV0VG9rZW5zIjoiMzciLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2 + IiwidG90YWxUb2tlbnMiOiIxOTg0NSJ9fX0sIm9mZnNldCI6IjkifQAAAACCeyJkb25lIjp7ImFn + ZW50SWQiOiJhZ2VudC1iMjdjYWYzYy1iN2RkLTRmYjctOWIzYi0xZGQ0OTZmMjQzYjgiLCJydW5J + ZCI6InJ1bi01NjQzMmFjMC03YzRkLTRjMGUtYTYxZS1iMjBlZmY3YmU5ZDMifSwib2Zmc2V0Ijoi + MTAifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Thu, 06 Aug 2026 15:25:08 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-ODFlOTU1YmMtNmJjYy00NTY4LTk1MmQtYjVhOGU0NmVmOTJk'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 06 Aug 2026 15:25:10 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Bt-Was-Udf-Cached: + - 'true' + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - ODFlOTU1YmMtNmJjYy00NTY4LTk1MmQtYjVhOGU0NmVmOTJk + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::qlktl-1786029910692-6458f81dcf24 + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-b27caf3c-b7dd-4fb7-9b3b-1dd496f243b8"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Thu, 06 Aug 2026 15:25:10 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + User-Agent: + - python-requests/2.34.2 + method: GET + uri: https://cursor-sdk-bridge/version + response: + body: + string: '{"version":"2.9.0","date_version":"20260805","ff_version":44,"commit":"787a5ad8b0dd2090d79c37513ba5cc3d21758ddc","deployment_mode":"lambda","deployment_type":"custom","brainstore_default":"force","brainstore_can_contain_row_refs":true,"skip_pg_config":"all","has_realtime_wal_bucket":true,"brainstore_wal_footer_version":"v3","brainstore_wal_use_efficient_format":true,"has_logs2":true,"brainstore_export_enabled":true,"js":true,"universal":true,"code_execution":true,"logs3_payload_max_bytes":5242880,"control_plane_telemetry":["status","memprof","usage"]}' + headers: + Connection: + - keep-alive + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 06 Aug 2026 15:25:10 GMT + Via: + - 1.1 8757e4d26d0f26e2f05769a88e8a5ace.cloudfront.net (CloudFront), 1.1 70fd8dd903406754b301439f9111e256.cloudfront.net + (CloudFront) + X-Amz-Cf-Id: + - Ss0YEvLkx62sgxQzE7gxBUIeur6GCuI4rObFW_nKD2H52MmGhLfkAg== + X-Amz-Cf-Pop: + - YTO53-P2 + - YTO50-P2 + X-Amzn-Trace-Id: + - Root=1-6a74a756-234e901069e7abad76019273;Parent=7c9b3bf1dd9c7968;Sampled=0;Lineage=1:24be3d11:0 + X-Cache: + - Miss from cloudfront + access-control-allow-credentials: + - 'true' + access-control-expose-headers: + - x-bt-cursor,x-bt-found-existing,x-bt-query-plan,x-bt-api-duration-ms,x-bt-brainstore-duration-ms,x-bt-internal-trace-id,x-bt-error-origin,x-bt-used-endpoint,x-bt-overflow-url + cache-control: + - no-store, no-cache, must-revalidate, proxy-revalidate + content-length: + - '557' + etag: + - W/"22d-RtkjTszsylxX5VGRelXw9TnJwV8" + expires: + - '0' + surrogate-control: + - no-store + vary: + - Origin + x-amz-apigw-id: + - Br8VqEMrIAMEspg= + x-amzn-Remapped-content-length: + - '557' + x-amzn-RequestId: + - 90c61597-36ec-47df-ba65-1e21f465cce7 + x-bt-internal-trace-id: + - 6a74a756000000004eca20768cb65953 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_multimodal_input_materializes_attachment.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_multimodal_input_materializes_attachment.yaml new file mode 100644 index 00000000..806c5b8e --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_multimodal_input_materializes_attachment.yaml @@ -0,0 +1,271 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-24e9e5e8-a921-4b13-aa72-7e5a999f3287","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:00:55 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAN17ImFnZW50SWQiOiAiYWdlbnQtMjRlOWU1ZTgtYTkyMS00YjEzLWFhNzItN2U1YTk5OWYz + Mjg3IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiQnJpZWZseSBkZXNjcmliZSB0aGlzIGltYWdlLiIs + ICJpbWFnZXMiOiBbeyJkYXRhIjogeyJkYXRhIjogIjxCQVNFNjRfREFUQT4iLCAibWltZVR5cGUi + OiAiaW1hZ2UvcG5nIn19XX0sICJvcHRpb25zIjogeyJhcGlLZXkiOiAiPFJFREFDVEVEPiJ9fQ== + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '364' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtMjRlOWU1ZTgtYTkyMS00YjEzLWFhNzItN2U1YTk5OWYz + Mjg3IiwicnVuX2lkIjoicnVuLTg5OWU0MDc5LTZjZDctNDc4OS04ODI0LTVlMDBhYzBhNzM0ZCIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADZeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC0yNGU5ZTVlOC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJydW5faWQiOiJydW4t + ODk5ZTQwNzktNmNkNy00Nzg5LTg4MjQtNWUwMGFjMGE3MzRkIiwidGV4dCI6IkkgbmVlZCB0byBk + ZXNjcmliZSB0aGUifX0sIm9mZnNldCI6IjIifQAAAADTeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0 + aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC0y + NGU5ZTVlOC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJydW5faWQiOiJydW4tODk5ZTQw + NzktNmNkNy00Nzg5LTg4MjQtNWUwMGFjMGE3MzRkIiwidGV4dCI6IiBhdHRhY2hlZCBpbWFnZS4i + fX0sIm9mZnNldCI6IjMifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1l + c3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC0yNGU5ZTVlOC1hOTIx + LTRiMTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJydW5faWQiOiJydW4tODk5ZTQwNzktNmNkNy00Nzg5 + LTg4MjQtNWUwMGFjMGE3MzRkIiwidGV4dCI6IlxuXG5UaGUgaW1hZ2UgaXMgYSBzb2xpZCwifX0s + Im9mZnNldCI6IjQifQAAAADYeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3Nh + Z2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC0yNGU5ZTVlOC1hOTIxLTRi + MTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJydW5faWQiOiJydW4tODk5ZTQwNzktNmNkNy00Nzg5LTg4 + MjQtNWUwMGFjMGE3MzRkIiwidGV4dCI6IiB1bmlmb3JtIGJsYWNrIHNxdWFyZSJ9fSwib2Zmc2V0 + IjoiNSJ9AAAAANx7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0 + eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTI0ZTllNWU4LWE5MjEtNGIxMy1hYTcy + LTdlNWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1bi04OTllNDA3OS02Y2Q3LTQ3ODktODgyNC01ZTAw + YWMwYTczNGQiLCJ0ZXh0IjoiIHdpdGggbm8gdmlzaWJsZSBkZXRhaWxzLCJ9fSwib2Zmc2V0Ijoi + NiJ9AAAAANd7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBl + IjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LTI0ZTllNWU4LWE5MjEtNGIxMy1hYTcyLTdl + NWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1bi04OTllNDA3OS02Y2Q3LTQ3ODktODgyNC01ZTAwYWMw + YTczNGQiLCJ0ZXh0IjoiIHBhdHRlcm5zLCBvciBvdGhlciAifX0sIm9mZnNldCI6IjcifQAAAADK + eyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5r + aW5nIiwiYWdlbnRfaWQiOiJhZ2VudC0yNGU5ZTVlOC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMy + ODciLCJydW5faWQiOiJydW4tODk5ZTQwNzktNmNkNy00Nzg5LTg4MjQtNWUwMGFjMGE3MzRkIiwi + dGV4dCI6ImNvbG9ycy4ifX0sIm9mZnNldCI6IjgifQAAAADeeyJzZGtNZXNzYWdlIjp7InR5cGUi + OiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2Vu + dC0yNGU5ZTVlOC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJydW5faWQiOiJydW4tODk5 + ZTQwNzktNmNkNy00Nzg5LTg4MjQtNWUwMGFjMGE3MzRkIiwidGV4dCI6IiIsInRoaW5raW5nX2R1 + cmF0aW9uX21zIjoyMzh9fSwib2Zmc2V0IjoiOSJ9AAAAAQR7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtMjRlOWU1ZTgtYTkyMS00YjEzLWFhNzItN2U1YTk5OWYzMjg3IiwicnVuX2lkIjoicnVuLTg5 + OWU0MDc5LTZjZDctNDc4OS04ODI0LTVlMDBhYzBhNzM0ZCIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IlRoZSJ9XX19fSwib2Zm + c2V0IjoiMTAifQAAAAESeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdl + Ijp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTI0ZTllNWU4LWE5MjEtNGIx + My1hYTcyLTdlNWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1bi04OTllNDA3OS02Y2Q3LTQ3ODktODgy + NC01ZTAwYWMwYTczNGQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50Ijpb + eyJ0eXBlIjoidGV4dCIsInRleHQiOiIgaW1hZ2UgaXMgYSBzb2xpZCJ9XX19fSwib2Zmc2V0Ijoi + MTEifQAAAAEHeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTI0ZTllNWU4LWE5MjEtNGIxMy1hYTcy + LTdlNWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1bi04OTllNDA3OS02Y2Q3LTQ3ODktODgyNC01ZTAw + YWMwYTczNGQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBl + IjoidGV4dCIsInRleHQiOiIgYmxhY2sifV19fX0sIm9mZnNldCI6IjEyIn0AAAABGHsic2RrTWVz + c2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50Iiwi + YWdlbnRfaWQiOiJhZ2VudC0yNGU5ZTVlOC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJy + dW5faWQiOiJydW4tODk5ZTQwNzktNmNkNy00Nzg5LTg4MjQtNWUwMGFjMGE3MzRkIiwibWVzc2Fn + ZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0Ijoi + IHNxdWFyZSB3aXRoIG5vIHZpc2libGUifV19fX0sIm9mZnNldCI6IjEzIn0AAAABE3sic2RrTWVz + c2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50Iiwi + YWdlbnRfaWQiOiJhZ2VudC0yNGU5ZTVlOC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJy + dW5faWQiOiJydW4tODk5ZTQwNzktNmNkNy00Nzg5LTg4MjQtNWUwMGFjMGE3MzRkIiwibWVzc2Fn + ZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0Ijoi + IGRldGFpbHMsIHBhdHRlcm5zIn1dfX19LCJvZmZzZXQiOiIxNCJ9AAAAAQV7InNka01lc3NhZ2Ui + OnsidHlwZSI6ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50 + X2lkIjoiYWdlbnQtMjRlOWU1ZTgtYTkyMS00YjEzLWFhNzItN2U1YTk5OWYzMjg3IiwicnVuX2lk + IjoicnVuLTg5OWU0MDc5LTZjZDctNDc4OS04ODI0LTVlMDBhYzBhNzM0ZCIsIm1lc3NhZ2UiOnsi + cm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6Iiwgb3Ii + fV19fX0sIm9mZnNldCI6IjE1In0AAAABB3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50 + IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC0yNGU5ZTVl + OC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJydW5faWQiOiJydW4tODk5ZTQwNzktNmNk + Ny00Nzg5LTg4MjQtNWUwMGFjMGE3MzRkIiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50Iiwi + Y29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiIG90aGVyIn1dfX19LCJvZmZzZXQiOiIx + NiJ9AAAAAQh7InNka01lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlw + ZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQtMjRlOWU1ZTgtYTkyMS00YjEzLWFhNzIt + N2U1YTk5OWYzMjg3IiwicnVuX2lkIjoicnVuLTg5OWU0MDc5LTZjZDctNDc4OS04ODI0LTVlMDBh + YzBhNzM0ZCIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUi + OiJ0ZXh0IiwidGV4dCI6IiBjb2xvcnMifV19fX0sIm9mZnNldCI6IjE3In0AAAABBXsic2RrTWVz + c2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50Iiwi + YWdlbnRfaWQiOiJhZ2VudC0yNGU5ZTVlOC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMyODciLCJy + dW5faWQiOiJydW4tODk5ZTQwNzktNmNkNy00Nzg5LTg4MjQtNWUwMGFjMGE3MzRkIiwibWVzc2Fn + ZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0Ijoi + IOKAlCJ9XX19fSwib2Zmc2V0IjoiMTgifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Np + c3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTI0 + ZTllNWU4LWE5MjEtNGIxMy1hYTcyLTdlNWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1bi04OTllNDA3 + OS02Y2Q3LTQ3ODktODgyNC01ZTAwYWMwYTczNGQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3Rh + bnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIganVzdCJ9XX19fSwib2Zmc2V0 + IjoiMTkifQAAAAELeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LTI0ZTllNWU4LWE5MjEtNGIxMy1h + YTcyLTdlNWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1bi04OTllNDA3OS02Y2Q3LTQ3ODktODgyNC01 + ZTAwYWMwYTczNGQiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiIgYSB1bmlmb3JtIn1dfX19LCJvZmZzZXQiOiIyMCJ9AAAAAQd7 + InNka01lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lz + dGFudCIsImFnZW50X2lkIjoiYWdlbnQtMjRlOWU1ZTgtYTkyMS00YjEzLWFhNzItN2U1YTk5OWYz + Mjg3IiwicnVuX2lkIjoicnVuLTg5OWU0MDc5LTZjZDctNDc4OS04ODI0LTVlMDBhYzBhNzM0ZCIs + Im1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0Iiwi + dGV4dCI6IiBibGFjayJ9XX19fSwib2Zmc2V0IjoiMjEifQAAAAEIeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6 + ImFnZW50LTI0ZTllNWU4LWE5MjEtNGIxMy1hYTcyLTdlNWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1 + bi04OTllNDA3OS02Y2Q3LTQ3ODktODgyNC01ZTAwYWMwYTczNGQiLCJtZXNzYWdlIjp7InJvbGUi + OiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQiOiIgZmllbGQuIn1d + fX19LCJvZmZzZXQiOiIyMiJ9AAAAASV7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVz + c2FnZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LTI0ZTllNWU4LWE5MjEtNGIx + My1hYTcyLTdlNWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1bi04OTllNDA3OS02Y2Q3LTQ3ODktODgy + NC01ZTAwYWMwYTczNGQiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTE0NTMsIm91dHB1dFRva2Vu + cyI6MTA2LCJjYWNoZVJlYWRUb2tlbnMiOjgzODQsImNhY2hlV3JpdGVUb2tlbnMiOjAsInRvdGFs + VG9rZW5zIjoxOTk0M319fSwib2Zmc2V0IjoiMjMifQAAAADKeyJzZGtNZXNzYWdlIjp7InR5cGUi + OiJzdGF0dXMiLCJtZXNzYWdlIjp7InR5cGUiOiJzdGF0dXMiLCJhZ2VudF9pZCI6ImFnZW50LTI0 + ZTllNWU4LWE5MjEtNGIxMy1hYTcyLTdlNWE5OTlmMzI4NyIsInJ1bl9pZCI6InJ1bi04OTllNDA3 + OS02Y2Q3LTQ3ODktODgyNC01ZTAwYWMwYTczNGQiLCJzdGF0dXMiOiJGSU5JU0hFRCJ9fSwib2Zm + c2V0IjoiMjQifQAAAAKIeyJyZXN1bHQiOnsiYWdlbnRJZCI6ImFnZW50LTI0ZTllNWU4LWE5MjEt + NGIxMy1hYTcyLTdlNWE5OTlmMzI4NyIsInJ1bklkIjoicnVuLTg5OWU0MDc5LTZjZDctNDc4OS04 + ODI0LTVlMDBhYzBhNzM0ZCIsInN0YXR1cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVE + IiwicmVzdWx0Ijp7InJ1bklkIjoicnVuLTg5OWU0MDc5LTZjZDctNDc4OS04ODI0LTVlMDBhYzBh + NzM0ZCIsImFnZW50SWQiOiJhZ2VudC0yNGU5ZTVlOC1hOTIxLTRiMTMtYWE3Mi03ZTVhOTk5ZjMy + ODciLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6IlRo + ZSBpbWFnZSBpcyBhIHNvbGlkIGJsYWNrIHNxdWFyZSB3aXRoIG5vIHZpc2libGUgZGV0YWlscywg + cGF0dGVybnMsIG9yIG90aGVyIGNvbG9ycyDigJQganVzdCBhIHVuaWZvcm0gYmxhY2sgZmllbGQu + IiwibW9kZWwiOnsiaWQiOiJjb21wb3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjU0MDAiLCJjcmVh + dGVkQXQiOiIyMDI2LTA4LTA1VDIxOjAwOjU1LjY3NFoiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6 + IjExNDUzIiwib3V0cHV0VG9rZW5zIjoiMTA2IiwiY2FjaGVSZWFkVG9rZW5zIjoiODM4NCIsInRv + dGFsVG9rZW5zIjoiMTk5NDMifX19LCJvZmZzZXQiOiIyNSJ9AAAAAIJ7ImRvbmUiOnsiYWdlbnRJ + ZCI6ImFnZW50LTI0ZTllNWU4LWE5MjEtNGIxMy1hYTcyLTdlNWE5OTlmMzI4NyIsInJ1bklkIjoi + cnVuLTg5OWU0MDc5LTZjZDctNDc4OS04ODI0LTVlMDBhYzBhNzM0ZCJ9LCJvZmZzZXQiOiIyNiJ9 + AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 21:00:57 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-24e9e5e8-a921-4b13-aa72-7e5a999f3287"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:01:01 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:01:01 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_resume_send_observe_finalizes_trace.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_resume_send_observe_finalizes_trace.yaml new file mode 100644 index 00000000..2f957929 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_resume_send_observe_finalizes_trace.yaml @@ -0,0 +1,415 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-a732bece-52b0-4206-87d2-6fc7f4b663e9","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:34:05 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKp7ImFnZW50SWQiOiAiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2 + M2U5IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgaW5p + dGlhbCB0cmFjaW5nIGNvbXBsZXRlIn0sICJvcHRpb25zIjogeyJhcGlLZXkiOiAiPFJFREFDVEVE + PiJ9fQ== + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '234' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2 + M2U5IiwicnVuX2lkIjoicnVuLTBlOGFlNjUyLTdkODktNDRlYy1iZjFkLWZkMjRjNGJiODQwNiIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADbeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1hNzMyYmVjZS01MmIwLTQyMDYtODdkMi02ZmM3ZjRiNjYzZTkiLCJydW5faWQiOiJydW4t + MGU4YWU2NTItN2Q4OS00NGVjLWJmMWQtZmQyNGM0YmI4NDA2IiwidGV4dCI6IlRoZSBleGFjdCBy + ZXBseSBcImN1cnNvciJ9fSwib2Zmc2V0IjoiMiJ9AAAAAN57InNka01lc3NhZ2UiOnsidHlwZSI6 + InRoaW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50 + LWE3MzJiZWNlLTUyYjAtNDIwNi04N2QyLTZmYzdmNGI2NjNlOSIsInJ1bl9pZCI6InJ1bi0wZThh + ZTY1Mi03ZDg5LTQ0ZWMtYmYxZC1mZDI0YzRiYjg0MDYiLCJ0ZXh0IjoiIGluaXRpYWwgdHJhY2lu + ZyBjb21wbGV0ZVwiIn19LCJvZmZzZXQiOiIzIn0AAAAA1nsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + YTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2M2U5IiwicnVuX2lkIjoicnVuLTBlOGFl + NjUyLTdkODktNDRlYy1iZjFkLWZkMjRjNGJiODQwNiIsInRleHQiOiIgaXMgYmVpbmcgcHJlcGFy + ZWQuIn19LCJvZmZzZXQiOiI0In0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmci + LCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtYTczMmJlY2Ut + NTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2M2U5IiwicnVuX2lkIjoicnVuLTBlOGFlNjUyLTdkODkt + NDRlYy1iZjFkLWZkMjRjNGJiODQwNiIsInRleHQiOiIiLCJ0aGlua2luZ19kdXJhdGlvbl9tcyI6 + MX19LCJvZmZzZXQiOiI1In0AAAABBnsic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50Iiwi + bWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC1hNzMyYmVjZS01 + MmIwLTQyMDYtODdkMi02ZmM3ZjRiNjYzZTkiLCJydW5faWQiOiJydW4tMGU4YWU2NTItN2Q4OS00 + NGVjLWJmMWQtZmQyNGM0YmI4NDA2IiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29u + dGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiY3Vyc29yIn1dfX19LCJvZmZzZXQiOiI2In0A + AAABGXsic2RrTWVzc2FnZSI6eyJ0eXBlIjoiYXNzaXN0YW50IiwibWVzc2FnZSI6eyJ0eXBlIjoi + YXNzaXN0YW50IiwiYWdlbnRfaWQiOiJhZ2VudC1hNzMyYmVjZS01MmIwLTQyMDYtODdkMi02ZmM3 + ZjRiNjYzZTkiLCJydW5faWQiOiJydW4tMGU4YWU2NTItN2Q4OS00NGVjLWJmMWQtZmQyNGM0YmI4 + NDA2IiwibWVzc2FnZSI6eyJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRl + eHQiLCJ0ZXh0IjoiIGluaXRpYWwgdHJhY2luZyBjb21wbGV0ZSJ9XX19fSwib2Zmc2V0IjoiNyJ9 + AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2FnZSI6eyJ0eXBlIjoidXNh + Z2UiLCJhZ2VudF9pZCI6ImFnZW50LWE3MzJiZWNlLTUyYjAtNDIwNi04N2QyLTZmYzdmNGI2NjNl + OSIsInJ1bl9pZCI6InJ1bi0wZThhZTY1Mi03ZDg5LTQ0ZWMtYmYxZC1mZDI0YzRiYjg0MDYiLCJ1 + c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzNzcsIm91dHB1dFRva2VucyI6NDAsImNhY2hlUmVhZFRv + a2VucyI6ODQxNiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tlbnMiOjE5ODMzfX19LCJv + ZmZzZXQiOiI4In0AAAAAyXsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwibWVzc2FnZSI6 + eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC1hNzMyYmVjZS01MmIwLTQyMDYtODdk + Mi02ZmM3ZjRiNjYzZTkiLCJydW5faWQiOiJydW4tMGU4YWU2NTItN2Q4OS00NGVjLWJmMWQtZmQy + NGM0YmI4NDA2Iiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6IjkifQAAAAIyeyJyZXN1 + bHQiOnsiYWdlbnRJZCI6ImFnZW50LWE3MzJiZWNlLTUyYjAtNDIwNi04N2QyLTZmYzdmNGI2NjNl + OSIsInJ1bklkIjoicnVuLTBlOGFlNjUyLTdkODktNDRlYy1iZjFkLWZkMjRjNGJiODQwNiIsInN0 + YXR1cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0Ijp7InJ1bklkIjoi + cnVuLTBlOGFlNjUyLTdkODktNDRlYy1iZjFkLWZkMjRjNGJiODQwNiIsImFnZW50SWQiOiJhZ2Vu + dC1hNzMyYmVjZS01MmIwLTQyMDYtODdkMi02ZmM3ZjRiNjYzZTkiLCJzdGF0dXMiOiJSVU5fTElG + RUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6ImN1cnNvciBpbml0aWFsIHRyYWNpbmcg + Y29tcGxldGUiLCJtb2RlbCI6eyJpZCI6ImNvbXBvc2VyLTIuNSJ9LCJkdXJhdGlvbk1zIjoiMzI5 + NSIsImNyZWF0ZWRBdCI6IjIwMjYtMDgtMDVUMjA6MzQ6MDUuNTg4WiIsInVzYWdlIjp7ImlucHV0 + VG9rZW5zIjoiMTEzNzciLCJvdXRwdXRUb2tlbnMiOiI0MCIsImNhY2hlUmVhZFRva2VucyI6Ijg0 + MTYiLCJ0b3RhbFRva2VucyI6IjE5ODMzIn19fSwib2Zmc2V0IjoiMTAifQAAAACCeyJkb25lIjp7 + ImFnZW50SWQiOiJhZ2VudC1hNzMyYmVjZS01MmIwLTQyMDYtODdkMi02ZmM3ZjRiNjYzZTkiLCJy + dW5JZCI6InJ1bi0wZThhZTY1Mi03ZDg5LTQ0ZWMtYmYxZC1mZDI0YzRiYjg0MDYifSwib2Zmc2V0 + IjoiMTEifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:34:07 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-a732bece-52b0-4206-87d2-6fc7f4b663e9"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:34:09 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-a732bece-52b0-4206-87d2-6fc7f4b663e9", "options": {"model": + {"id": "composer-2.5"}, "apiKey": "", "local": {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '334' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/ResumeAgent + response: + body: + string: '{"agentId":"agent-a732bece-52b0-4206-87d2-6fc7f4b663e9","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:34:09 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKp7ImFnZW50SWQiOiAiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2 + M2U5IiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgcmVz + dW1lZCB0cmFjaW5nIGNvbXBsZXRlIn0sICJvcHRpb25zIjogeyJhcGlLZXkiOiAiPFJFREFDVEVE + PiJ9fQ== + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '234' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2 + M2U5IiwicnVuX2lkIjoicnVuLTI2YmIyMDQ2LWY0OGMtNDU2Zi1hN2QzLTQ4M2Y2Y2VkNDM1ZSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC1hNzMyYmVjZS01MmIwLTQyMDYtODdkMi02ZmM3ZjRiNjYzZTkiLCJydW5faWQiOiJydW4t + MjZiYjIwNDYtZjQ4Yy00NTZmLWE3ZDMtNDgzZjZjZWQ0MzVlIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Xsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + YTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2M2U5IiwicnVuX2lkIjoicnVuLTI2YmIy + MDQ2LWY0OGMtNDU2Zi1hN2QzLTQ4M2Y2Y2VkNDM1ZSIsInRleHQiOiIgZXhhY3RseTogXCJjdXJz + b3IgcmVzdW1lZCJ9fSwib2Zmc2V0IjoiMyJ9AAAAANZ7InNka01lc3NhZ2UiOnsidHlwZSI6InRo + aW5raW5nIiwibWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LWE3 + MzJiZWNlLTUyYjAtNDIwNi04N2QyLTZmYzdmNGI2NjNlOSIsInJ1bl9pZCI6InJ1bi0yNmJiMjA0 + Ni1mNDhjLTQ1NmYtYTdkMy00ODNmNmNlZDQzNWUiLCJ0ZXh0IjoiIHRyYWNpbmcgY29tcGxldGVc + IiJ9fSwib2Zmc2V0IjoiNCJ9AAAAANx7InNka01lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwi + bWVzc2FnZSI6eyJ0eXBlIjoidGhpbmtpbmciLCJhZ2VudF9pZCI6ImFnZW50LWE3MzJiZWNlLTUy + YjAtNDIwNi04N2QyLTZmYzdmNGI2NjNlOSIsInJ1bl9pZCI6InJ1bi0yNmJiMjA0Ni1mNDhjLTQ1 + NmYtYTdkMy00ODNmNmNlZDQzNWUiLCJ0ZXh0IjoiIiwidGhpbmtpbmdfZHVyYXRpb25fbXMiOjF9 + fSwib2Zmc2V0IjoiNSJ9AAAAAQZ7InNka01lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsIm1l + c3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQtYTczMmJlY2UtNTJi + MC00MjA2LTg3ZDItNmZjN2Y0YjY2M2U5IiwicnVuX2lkIjoicnVuLTI2YmIyMDQ2LWY0OGMtNDU2 + Zi1hN2QzLTQ4M2Y2Y2VkNDM1ZSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRl + bnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6ImN1cnNvciJ9XX19fSwib2Zmc2V0IjoiNiJ9AAAA + ARl7InNka01lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFz + c2lzdGFudCIsImFnZW50X2lkIjoiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0 + YjY2M2U5IiwicnVuX2lkIjoicnVuLTI2YmIyMDQ2LWY0OGMtNDU2Zi1hN2QzLTQ4M2Y2Y2VkNDM1 + ZSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0 + IiwidGV4dCI6IiByZXN1bWVkIHRyYWNpbmcgY29tcGxldGUifV19fX0sIm9mZnNldCI6IjcifQAA + AAEjeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ1c2FnZSIsIm1lc3NhZ2UiOnsidHlwZSI6InVzYWdl + IiwiYWdlbnRfaWQiOiJhZ2VudC1hNzMyYmVjZS01MmIwLTQyMDYtODdkMi02ZmM3ZjRiNjYzZTki + LCJydW5faWQiOiJydW4tMjZiYjIwNDYtZjQ4Yy00NTZmLWE3ZDMtNDgzZjZjZWQ0MzVlIiwidXNh + Z2UiOnsiaW5wdXRUb2tlbnMiOjExNDYyLCJvdXRwdXRUb2tlbnMiOjMxLCJjYWNoZVJlYWRUb2tl + bnMiOjg0MTYsImNhY2hlV3JpdGVUb2tlbnMiOjAsInRvdGFsVG9rZW5zIjoxOTkwOX19fSwib2Zm + c2V0IjoiOCJ9AAAAAMl7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsi + dHlwZSI6InN0YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDIt + NmZjN2Y0YjY2M2U5IiwicnVuX2lkIjoicnVuLTI2YmIyMDQ2LWY0OGMtNDU2Zi1hN2QzLTQ4M2Y2 + Y2VkNDM1ZSIsInN0YXR1cyI6IkZJTklTSEVEIn19LCJvZmZzZXQiOiI5In0AAAACMnsicmVzdWx0 + Ijp7ImFnZW50SWQiOiJhZ2VudC1hNzMyYmVjZS01MmIwLTQyMDYtODdkMi02ZmM3ZjRiNjYzZTki + LCJydW5JZCI6InJ1bi0yNmJiMjA0Ni1mNDhjLTQ1NmYtYTdkMy00ODNmNmNlZDQzNWUiLCJzdGF0 + dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJlc3VsdCI6eyJydW5JZCI6InJ1 + bi0yNmJiMjA0Ni1mNDhjLTQ1NmYtYTdkMy00ODNmNmNlZDQzNWUiLCJhZ2VudElkIjoiYWdlbnQt + YTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2M2U5Iiwic3RhdHVzIjoiUlVOX0xJRkVD + WUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3IgcmVzdW1lZCB0cmFjaW5nIGNv + bXBsZXRlIiwibW9kZWwiOnsiaWQiOiJjb21wb3Nlci0yLjUifSwiZHVyYXRpb25NcyI6IjE1NDgi + LCJjcmVhdGVkQXQiOiIyMDI2LTA4LTA1VDIwOjM0OjA5LjIxNVoiLCJ1c2FnZSI6eyJpbnB1dFRv + a2VucyI6IjExNDYyIiwib3V0cHV0VG9rZW5zIjoiMzEiLCJjYWNoZVJlYWRUb2tlbnMiOiI4NDE2 + IiwidG90YWxUb2tlbnMiOiIxOTkwOSJ9fX0sIm9mZnNldCI6IjEwIn0AAAAAgnsiZG9uZSI6eyJh + Z2VudElkIjoiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0YjY2M2U5IiwicnVu + SWQiOiJydW4tMjZiYjIwNDYtZjQ4Yy00NTZmLWE3ZDMtNDgzZjZjZWQ0MzVlIn0sIm9mZnNldCI6 + IjExIn0CAAAAAnt9 + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:34:09 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: "\0\0\0\05{\"runId\": \"run-26bb2046-f48c-456f-a7d3-483f6ced435e\"}" + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '58' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/ObserveRun + response: + body: + string: !!binary | + AAAAAjF7InJlc3VsdCI6eyJhZ2VudElkIjoiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDIt + NmZjN2Y0YjY2M2U5IiwicnVuSWQiOiJydW4tMjZiYjIwNDYtZjQ4Yy00NTZmLWE3ZDMtNDgzZjZj + ZWQ0MzVlIiwic3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQi + OnsicnVuSWQiOiJydW4tMjZiYjIwNDYtZjQ4Yy00NTZmLWE3ZDMtNDgzZjZjZWQ0MzVlIiwiYWdl + bnRJZCI6ImFnZW50LWE3MzJiZWNlLTUyYjAtNDIwNi04N2QyLTZmYzdmNGI2NjNlOSIsInN0YXR1 + cyI6IlJVTl9MSUZFQ1lDTEVfU1RBVFVTX0ZJTklTSEVEIiwicmVzdWx0IjoiY3Vyc29yIHJlc3Vt + ZWQgdHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0 + aW9uTXMiOiIxNTQ4IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDozNDowOS4yMTVaIiwidXNh + Z2UiOnsiaW5wdXRUb2tlbnMiOiIxMTQ2MiIsIm91dHB1dFRva2VucyI6IjMxIiwiY2FjaGVSZWFk + VG9rZW5zIjoiODQxNiIsInRvdGFsVG9rZW5zIjoiMTk5MDkifX19LCJvZmZzZXQiOiIxIn0AAAAA + gXsiZG9uZSI6eyJhZ2VudElkIjoiYWdlbnQtYTczMmJlY2UtNTJiMC00MjA2LTg3ZDItNmZjN2Y0 + YjY2M2U5IiwicnVuSWQiOiJydW4tMjZiYjIwNDYtZjQ4Yy00NTZmLWE3ZDMtNDgzZjZjZWQ0MzVl + In0sIm9mZnNldCI6IjIifQIAAAACe30= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:34:10 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-a732bece-52b0-4206-87d2-6fc7f4b663e9"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:34:10 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:34:10 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_send_error_propagates_and_logs_parent_error.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_send_error_propagates_and_logs_parent_error.yaml new file mode 100644 index 00000000..674c34c2 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_send_error_propagates_and_logs_parent_error.yaml @@ -0,0 +1,190 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-1a16cd78-6bdb-465f-a936-1d5fd4fc705d","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:02:06 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAANN7ImFnZW50SWQiOiAiYWdlbnQtMWExNmNkNzgtNmJkYi00NjVmLWE5MzYtMWQ1ZmQ0ZmM3 + MDVkIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiVGhpcyByZXF1ZXN0IG11c3QgZmFpbCBiZWZvcmUg + ZXhlY3V0aW9uLiJ9LCAib3B0aW9ucyI6IHsibW9kZWwiOiB7ImlkIjogImJyYWludHJ1c3QtaW52 + YWxpZC1jdXJzb3ItbW9kZWwifSwgImFwaUtleSI6ICI8UkVEQUNURUQ+In19 + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '275' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AgAACIh7ImVycm9yIjp7ImNvZGUiOiJpbnZhbGlkX2FyZ3VtZW50IiwibWVzc2FnZSI6IkNhbm5v + dCB1c2UgdGhpcyBtb2RlbDogYnJhaW50cnVzdC1pbnZhbGlkLWN1cnNvci1tb2RlbC4gQXZhaWxh + YmxlIG1vZGVsczogZGVmYXVsdCwgZ3Jvay00LjUsIGNvbXBvc2VyLTIuNSwgY2xhdWRlLW9wdXMt + NSwgY2xhdWRlLW9wdXMtNC04LCBncHQtNS42LXNvbCwgZ3B0LTUuNSwgY2xhdWRlLWZhYmxlLTUs + IGNsYXVkZS1zb25uZXQtNSwgZ3B0LTUuNi10ZXJyYSwgY2xhdWRlLXNvbm5ldC00LTYsIGNvbXBv + c2VyLTIsIGdwdC01LjMtY29kZXgsIGNsYXVkZS1vcHVzLTQtNywgZ3B0LTUuNCwgY2xhdWRlLW9w + dXMtNC02LCBjbGF1ZGUtb3B1cy00LTUsIGdwdC01LjIsIGdwdC01LjYtbHVuYSwgZ2VtaW5pLTMu + Ni1mbGFzaCwgZ2VtaW5pLTMuMS1wcm8sIGdwdC01LjQtbWluaSwgZ3B0LTUuNC1uYW5vLCBjbGF1 + ZGUtaGFpa3UtNC01LCBjbGF1ZGUtc29ubmV0LTQtNSwgZ3B0LTUuMSwgZ2VtaW5pLTMtZmxhc2gs + IGdlbWluaS0zLjUtZmxhc2gsIGNsYXVkZS1zb25uZXQtNCwgZ3B0LTUtbWluaSwgZ2VtaW5pLTIu + NS1mbGFzaCwga2ltaS1rMywga2ltaS1rMi43LWNvZGUsIGdsbS01LjIuIFVzZSBDdXJzb3IubW9k + ZWxzLmxpc3QoKSB0byBkaXNjb3ZlciB2YWxpZCBzZWxlY3Rpb25zLiIsImRldGFpbHMiOlt7InR5 + cGUiOiJzZGsudjEuU2RrRXJyb3JEZXRhaWxzIiwiZGVidWciOnsibWVzc2FnZSI6IkNhbm5vdCB1 + c2UgdGhpcyBtb2RlbDogYnJhaW50cnVzdC1pbnZhbGlkLWN1cnNvci1tb2RlbC4gQXZhaWxhYmxl + IG1vZGVsczogZGVmYXVsdCwgZ3Jvay00LjUsIGNvbXBvc2VyLTIuNSwgY2xhdWRlLW9wdXMtNSwg + Y2xhdWRlLW9wdXMtNC04LCBncHQtNS42LXNvbCwgZ3B0LTUuNSwgY2xhdWRlLWZhYmxlLTUsIGNs + YXVkZS1zb25uZXQtNSwgZ3B0LTUuNi10ZXJyYSwgY2xhdWRlLXNvbm5ldC00LTYsIGNvbXBvc2Vy + LTIsIGdwdC01LjMtY29kZXgsIGNsYXVkZS1vcHVzLTQtNywgZ3B0LTUuNCwgY2xhdWRlLW9wdXMt + NC02LCBjbGF1ZGUtb3B1cy00LTUsIGdwdC01LjIsIGdwdC01LjYtbHVuYSwgZ2VtaW5pLTMuNi1m + bGFzaCwgZ2VtaW5pLTMuMS1wcm8sIGdwdC01LjQtbWluaSwgZ3B0LTUuNC1uYW5vLCBjbGF1ZGUt + aGFpa3UtNC01LCBjbGF1ZGUtc29ubmV0LTQtNSwgZ3B0LTUuMSwgZ2VtaW5pLTMtZmxhc2gsIGdl + bWluaS0zLjUtZmxhc2gsIGNsYXVkZS1zb25uZXQtNCwgZ3B0LTUtbWluaSwgZ2VtaW5pLTIuNS1m + bGFzaCwga2ltaS1rMywga2ltaS1rMi43LWNvZGUsIGdsbS01LjIuIFVzZSBDdXJzb3IubW9kZWxz + Lmxpc3QoKSB0byBkaXNjb3ZlciB2YWxpZCBzZWxlY3Rpb25zLiJ9LCJ2YWx1ZSI6Ikd1Y0VRMkZ1 + Ym05MElIVnpaU0IwYUdseklHMXZaR1ZzT2lCaWNtRnBiblJ5ZFhOMExXbHVkbUZzYVdRdFkzVnlj + Mjl5TFcxdlpHVnNMaUJCZG1GcGJHRmliR1VnYlc5a1pXeHpPaUJrWldaaGRXeDBMQ0JuY205ckxU + UXVOU3dnWTI5dGNHOXpaWEl0TWk0MUxDQmpiR0YxWkdVdGIzQjFjeTAxTENCamJHRjFaR1V0YjNC + MWN5MDBMVGdzSUdkd2RDMDFMall0YzI5c0xDQm5jSFF0TlM0MUxDQmpiR0YxWkdVdFptRmliR1V0 + TlN3Z1kyeGhkV1JsTFhOdmJtNWxkQzAxTENCbmNIUXROUzQyTFhSbGNuSmhMQ0JqYkdGMVpHVXRj + Mjl1Ym1WMExUUXROaXdnWTI5dGNHOXpaWEl0TWl3Z1ozQjBMVFV1TXkxamIyUmxlQ3dnWTJ4aGRX + UmxMVzl3ZFhNdE5DMDNMQ0JuY0hRdE5TNDBMQ0JqYkdGMVpHVXRiM0IxY3kwMExUWXNJR05zWVhW + a1pTMXZjSFZ6TFRRdE5Td2daM0IwTFRVdU1pd2daM0IwTFRVdU5pMXNkVzVoTENCblpXMXBibWt0 + TXk0MkxXWnNZWE5vTENCblpXMXBibWt0TXk0eExYQnlieXdnWjNCMExUVXVOQzF0YVc1cExDQm5j + SFF0TlM0MExXNWhibThzSUdOc1lYVmtaUzFvWVdscmRTMDBMVFVzSUdOc1lYVmtaUzF6YjI1dVpY + UXROQzAxTENCbmNIUXROUzR4TENCblpXMXBibWt0TXkxbWJHRnphQ3dnWjJWdGFXNXBMVE11TlMx + bWJHRnphQ3dnWTJ4aGRXUmxMWE52Ym01bGRDMDBMQ0JuY0hRdE5TMXRhVzVwTENCblpXMXBibWt0 + TWk0MUxXWnNZWE5vTENCcmFXMXBMV3N6TENCcmFXMXBMV3N5TGpjdFkyOWtaU3dnWjJ4dExUVXVN + aTRnVlhObElFTjFjbk52Y2k1dGIyUmxiSE11YkdsemRDZ3BJSFJ2SUdScGMyTnZkbVZ5SUhaaGJH + bGtJSE5sYkdWamRHbHZibk11In1dfX0= + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 21:02:06 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-1a16cd78-6bdb-465f-a936-1d5fd4fc705d"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:02:06 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 21:02:06 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[events].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[events].yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[events].yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[iter_text].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[iter_text].yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[iter_text].yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[iteration].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[iteration].yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[iteration].yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[messages].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[messages].yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[messages].yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[stream].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[stream].yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[stream].yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[text].yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[text].yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_consumption_paths_finalize_once[text].yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_wait_traces_cursor_owned_model_turn.yaml b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_wait_traces_cursor_owned_model_turn.yaml new file mode 100644 index 00000000..d753f427 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/cassettes/latest/test_sync_wait_traces_cursor_owned_model_turn.yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"options": {"model": {"id": "composer-2.5"}, "apiKey": "", "local": + {"cwd": ""}}}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '277' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CreateAgent + response: + body: + string: '{"agentId":"agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3","model":{"id":"composer-2.5"}}' + headers: + connection: + - keep-alive + content-length: + - '86' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:21 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: !!binary | + AAAAAKJ7ImFnZW50SWQiOiAiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwgIm1lc3NhZ2UiOiB7InRleHQiOiAiUmVwbHkgd2l0aCBleGFjdGx5OiBjdXJzb3IgdHJh + Y2luZyBjb21wbGV0ZSJ9LCAib3B0aW9ucyI6IHsiYXBpS2V5IjogIjxSRURBQ1RFRD4ifX0= + headers: + accept: + - application/connect+json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '226' + content-type: + - application/connect+json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/Send + response: + body: + string: !!binary | + AAAAAMh7InNka01lc3NhZ2UiOnsidHlwZSI6InN0YXR1cyIsIm1lc3NhZ2UiOnsidHlwZSI6InN0 + YXR1cyIsImFnZW50X2lkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJm + MGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIs + InN0YXR1cyI6IlJVTk5JTkcifX0sIm9mZnNldCI6IjEifQAAAADaeyJzZGtNZXNzYWdlIjp7InR5 + cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2UiOnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJh + Z2VudC04YjYwYjBiYy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4t + YzM1MmZjYjAtYmI3OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwidGV4dCI6IlByZXBhcmluZyB0 + byByZXBseSB3aXRoIn19LCJvZmZzZXQiOiIyIn0AAAAA3Hsic2RrTWVzc2FnZSI6eyJ0eXBlIjoi + dGhpbmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQt + OGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJm + Y2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgZXhhY3RseSBcImN1cnNv + ciB0cmFjaW5nIn19LCJvZmZzZXQiOiIzIn0AAAAAz3sic2RrTWVzc2FnZSI6eyJ0eXBlIjoidGhp + bmtpbmciLCJtZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsImFnZW50X2lkIjoiYWdlbnQtOGI2 + MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMzNTJmY2Iw + LWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsInRleHQiOiIgY29tcGxldGVcIi4ifX0sIm9m + ZnNldCI6IjQifQAAAADceyJzZGtNZXNzYWdlIjp7InR5cGUiOiJ0aGlua2luZyIsIm1lc3NhZ2Ui + OnsidHlwZSI6InRoaW5raW5nIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3OS00MzFhLTgwM2Mt + Y2Q1ZGUxZDRjM2IxIiwidGV4dCI6IiIsInRoaW5raW5nX2R1cmF0aW9uX21zIjoxfX0sIm9mZnNl + dCI6IjUifQAAAAEGeyJzZGtNZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7 + InR5cGUiOiJhc3Npc3RhbnQiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJtZXNzYWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0 + eXBlIjoidGV4dCIsInRleHQiOiJjdXJzb3IifV19fX0sIm9mZnNldCI6IjYifQAAAAEIeyJzZGtN + ZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQiLCJtZXNzYWdlIjp7InR5cGUiOiJhc3Npc3RhbnQi + LCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYyZjBlMyIs + InJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEiLCJtZXNz + YWdlIjp7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjpbeyJ0eXBlIjoidGV4dCIsInRleHQi + OiIgdHJhY2luZyJ9XX19fSwib2Zmc2V0IjoiNyJ9AAAAAQl7InNka01lc3NhZ2UiOnsidHlwZSI6 + ImFzc2lzdGFudCIsIm1lc3NhZ2UiOnsidHlwZSI6ImFzc2lzdGFudCIsImFnZW50X2lkIjoiYWdl + bnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwicnVuX2lkIjoicnVuLWMz + NTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSIsIm1lc3NhZ2UiOnsicm9sZSI6ImFz + c2lzdGFudCIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiBjb21wbGV0ZSJ9XX19 + fSwib2Zmc2V0IjoiOCJ9AAAAASN7InNka01lc3NhZ2UiOnsidHlwZSI6InVzYWdlIiwibWVzc2Fn + ZSI6eyJ0eXBlIjoidXNhZ2UiLCJhZ2VudF9pZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1i + YzM1LTM5NTg0NWYyZjBlMyIsInJ1bl9pZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJ1c2FnZSI6eyJpbnB1dFRva2VucyI6MTEzODEsIm91dHB1dFRva2VucyI6 + MzYsImNhY2hlUmVhZFRva2VucyI6NDI1NiwiY2FjaGVXcml0ZVRva2VucyI6MCwidG90YWxUb2tl + bnMiOjE1NjczfX19LCJvZmZzZXQiOiI5In0AAAAAynsic2RrTWVzc2FnZSI6eyJ0eXBlIjoic3Rh + dHVzIiwibWVzc2FnZSI6eyJ0eXBlIjoic3RhdHVzIiwiYWdlbnRfaWQiOiJhZ2VudC04YjYwYjBi + Yy0xMGY2LTQ2N2QtYmMzNS0zOTU4NDVmMmYwZTMiLCJydW5faWQiOiJydW4tYzM1MmZjYjAtYmI3 + OS00MzFhLTgwM2MtY2Q1ZGUxZDRjM2IxIiwic3RhdHVzIjoiRklOSVNIRUQifX0sIm9mZnNldCI6 + IjEwIn0AAAACKnsicmVzdWx0Ijp7ImFnZW50SWQiOiJhZ2VudC04YjYwYjBiYy0xMGY2LTQ2N2Qt + YmMzNS0zOTU4NDVmMmYwZTMiLCJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1j + ZDVkZTFkNGMzYjEiLCJzdGF0dXMiOiJSVU5fTElGRUNZQ0xFX1NUQVRVU19GSU5JU0hFRCIsInJl + c3VsdCI6eyJydW5JZCI6InJ1bi1jMzUyZmNiMC1iYjc5LTQzMWEtODAzYy1jZDVkZTFkNGMzYjEi + LCJhZ2VudElkIjoiYWdlbnQtOGI2MGIwYmMtMTBmNi00NjdkLWJjMzUtMzk1ODQ1ZjJmMGUzIiwi + c3RhdHVzIjoiUlVOX0xJRkVDWUNMRV9TVEFUVVNfRklOSVNIRUQiLCJyZXN1bHQiOiJjdXJzb3Ig + dHJhY2luZyBjb21wbGV0ZSIsIm1vZGVsIjp7ImlkIjoiY29tcG9zZXItMi41In0sImR1cmF0aW9u + TXMiOiIzNjk0IiwiY3JlYXRlZEF0IjoiMjAyNi0wOC0wNVQyMDoyNjoyMS45MjZaIiwidXNhZ2Ui + OnsiaW5wdXRUb2tlbnMiOiIxMTM4MSIsIm91dHB1dFRva2VucyI6IjM2IiwiY2FjaGVSZWFkVG9r + ZW5zIjoiNDI1NiIsInRvdGFsVG9rZW5zIjoiMTU2NzMifX19LCJvZmZzZXQiOiIxMSJ9AAAAAIJ7 + ImRvbmUiOnsiYWdlbnRJZCI6ImFnZW50LThiNjBiMGJjLTEwZjYtNDY3ZC1iYzM1LTM5NTg0NWYy + ZjBlMyIsInJ1bklkIjoicnVuLWMzNTJmY2IwLWJiNzktNDMxYS04MDNjLWNkNWRlMWQ0YzNiMSJ9 + LCJvZmZzZXQiOiIxMiJ9AgAAAAJ7fQ== + headers: + connection: + - keep-alive + content-type: + - application/connect+json + date: + - Wed, 05 Aug 2026 20:26:23 GMT + keep-alive: + - timeout=5 + transfer-encoding: + - chunked + status: + code: 200 + message: OK +- request: + body: '{"agentId": "agent-8b60b0bc-10f6-467d-bc35-395845f2f0e3"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '57' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkAgentService/CloseAgent + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: '{"graceSeconds": 0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connect-protocol-version: + - '1' + connection: + - keep-alive + content-length: + - '19' + content-type: + - application/json + user-agent: + - python-httpx/0.28.1 + method: POST + uri: http://cursor-sdk-bridge/sdk.v1.SdkBridgeControlService/Shutdown + response: + body: + string: '{}' + headers: + connection: + - keep-alive + content-length: + - '2' + content-type: + - application/json + date: + - Wed, 05 Aug 2026 20:26:25 GMT + keep-alive: + - timeout=5 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, zstd + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.34.2 + method: POST + uri: https://cursor-sdk-bridge/api/apikey/login + response: + body: + string: '{"org_info":[{"id":"5abfae3a-7aa7-4653-a9c8-b3efcb18f584","name":"Braintrust + SDKs","api_url":"https://api.braintrust.dev","git_metadata":{"collect":"some","fields":["commit","branch","tag","dirty","author_name","author_email","commit_message","commit_time"]},"is_universal_api":null,"proxy_url":"https://api.braintrust.dev","realtime_url":"wss://realtime.braintrustapi.com"}]}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, + Content-Type, Date, X-Api-Version + Access-Control-Allow-Methods: + - GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - public, max-age=0, must-revalidate + Content-Length: + - '376' + Content-Security-Policy: + - 'script-src ''self'' ''unsafe-eval'' ''wasm-unsafe-eval'' ''strict-dynamic'' + ''nonce-YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy'' *.js.stripe.com + js.stripe.com maps.googleapis.com ; style-src ''self'' ''unsafe-inline'' *.braintrust.dev + btcm6qilbbhv4yi1.public.blob.vercel-storage.com fonts.googleapis.com www.gstatic.com + d4tuoctqmanu0.cloudfront.net; font-src ''self'' data: fonts.gstatic.com btcm6qilbbhv4yi1.public.blob.vercel-storage.com + cdn.jsdelivr.net d4tuoctqmanu0.cloudfront.net fonts.googleapis.com mintlify-assets.b-cdn.net + fonts.cdnfonts.com; object-src ''none''; base-uri ''self''; form-action ''self'' + https://www.facebook.com; frame-ancestors ''self''; worker-src ''self'' blob:; + report-uri https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16; + report-to csp-endpoint-0' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 05 Aug 2026 20:26:26 GMT + Etag: + - '"13vsc5ye8flag"' + Reporting-Endpoints: + - csp-endpoint-0="https://o4507221741076480.ingest.us.sentry.io/api/4507221754380288/security/?sentry_key=27fa5ac907cf7c6ce4a1ab2a03f805b4&sentry_environment=production&sentry_release=16" + Server: + - Vercel + Strict-Transport-Security: + - max-age=63072000 + X-Clerk-Auth-Message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + X-Clerk-Auth-Reason: + - token-invalid + X-Clerk-Auth-Status: + - signed-out + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Matched-Path: + - /api/apikey/login + X-Nonce: + - YjVmMTdiNjYtZjQ3OS00YjJjLWJiOGQtNmZmOWUzNzQyM2Yy + X-Vercel-Cache: + - MISS + X-Vercel-Id: + - yul1::iad1::mrfrm-1785961586410-6a87821dcc30 + status: + code: 200 + message: OK +version: 1 diff --git a/py/src/braintrust/integrations/cursor_sdk/integration.py b/py/src/braintrust/integrations/cursor_sdk/integration.py new file mode 100644 index 00000000..a7857efc --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/integration.py @@ -0,0 +1,15 @@ +"""Cursor SDK integration orchestration.""" + +from braintrust.integrations.base import BaseIntegration + +from .patchers import AgentLifecyclePatcher, CustomToolDispatchPatcher, RunLifecyclePatcher + + +class CursorSDKIntegration(BaseIntegration): + """Braintrust instrumentation for Cursor's Python agent SDK.""" + + name = "cursor_sdk" + import_names = ("cursor_sdk",) + distribution_names = ("cursor-sdk",) + min_version = "1.0.25" + patchers = (RunLifecyclePatcher, AgentLifecyclePatcher, CustomToolDispatchPatcher) diff --git a/py/src/braintrust/integrations/cursor_sdk/patchers.py b/py/src/braintrust/integrations/cursor_sdk/patchers.py new file mode 100644 index 00000000..a2055980 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/patchers.py @@ -0,0 +1,123 @@ +"""Patchers for Cursor SDK agent runs and stream lifecycles.""" + +from braintrust.integrations.base import CompositeFunctionWrapperPatcher, FunctionWrapperPatcher + +from .tracing import ( + _wrap_apply_event_state, + _wrap_async_cancel, + _wrap_async_close, + _wrap_async_observe, + _wrap_async_send, + _wrap_async_wait, + _wrap_sync_cancel, + _wrap_sync_close, + _wrap_sync_observe, + _wrap_sync_send, + _wrap_sync_wait, + _wrap_tool_dispatch, +) + + +class AgentSendPatcher(FunctionWrapperPatcher): + name = "cursor_sdk.agent.send" + target_path = "Agent.send" + wrapper = staticmethod(_wrap_sync_send) + + +class AsyncAgentSendPatcher(FunctionWrapperPatcher): + name = "cursor_sdk.async_agent.send" + target_path = "AsyncAgent.send" + wrapper = staticmethod(_wrap_async_send) + + +class AgentClosePatcher(FunctionWrapperPatcher): + name = "cursor_sdk.agent.close" + target_path = "Agent.close" + wrapper = staticmethod(_wrap_sync_close) + + +class AsyncAgentClosePatcher(FunctionWrapperPatcher): + name = "cursor_sdk.async_agent.close" + target_path = "AsyncAgent.close" + wrapper = staticmethod(_wrap_async_close) + + +class AgentLifecyclePatcher(CompositeFunctionWrapperPatcher): + name = "cursor_sdk.agent" + sub_patchers = (AgentSendPatcher, AsyncAgentSendPatcher, AgentClosePatcher, AsyncAgentClosePatcher) + + +class RunApplyEventStatePatcher(FunctionWrapperPatcher): + """Trace stream events at the one point `Run` and `AsyncRun` share. + + Both `_handle_event` implementations are thin shims over this synchronous + base method, and every consumption path (`wait`, `events`, `stream`, + `messages`, `iter_text`, iteration) routes through them. + """ + + name = "cursor_sdk.run.apply_event_state" + target_module = "cursor_sdk._run_base" + target_path = "_RunBase._apply_event_state" + wrapper = staticmethod(_wrap_apply_event_state) + + +class RunWaitPatcher(FunctionWrapperPatcher): + name = "cursor_sdk.run.wait" + target_module = "cursor_sdk._run" + target_path = "Run.wait" + wrapper = staticmethod(_wrap_sync_wait) + + +class AsyncRunWaitPatcher(FunctionWrapperPatcher): + name = "cursor_sdk.async_run.wait" + target_module = "cursor_sdk._async_run" + target_path = "AsyncRun.wait" + wrapper = staticmethod(_wrap_async_wait) + + +class RunObservePatcher(FunctionWrapperPatcher): + name = "cursor_sdk.run.observe" + target_module = "cursor_sdk._run" + target_path = "Run.observe" + wrapper = staticmethod(_wrap_sync_observe) + + +class AsyncRunObservePatcher(FunctionWrapperPatcher): + name = "cursor_sdk.async_run.observe" + target_module = "cursor_sdk._async_run" + target_path = "AsyncRun.observe" + wrapper = staticmethod(_wrap_async_observe) + + +class RunCancelPatcher(FunctionWrapperPatcher): + name = "cursor_sdk.run.cancel" + target_module = "cursor_sdk._run" + target_path = "Run.cancel" + wrapper = staticmethod(_wrap_sync_cancel) + + +class AsyncRunCancelPatcher(FunctionWrapperPatcher): + name = "cursor_sdk.async_run.cancel" + target_module = "cursor_sdk._async_run" + target_path = "AsyncRun.cancel" + wrapper = staticmethod(_wrap_async_cancel) + + +class RunLifecyclePatcher(CompositeFunctionWrapperPatcher): + name = "cursor_sdk.run" + sub_patchers = ( + RunApplyEventStatePatcher, + RunWaitPatcher, + AsyncRunWaitPatcher, + RunObservePatcher, + AsyncRunObservePatcher, + RunCancelPatcher, + AsyncRunCancelPatcher, + ) + + +class CustomToolDispatchPatcher(FunctionWrapperPatcher): + name = "cursor_sdk.custom_tool" + target_module = "cursor_sdk._tool_callback" + target_path = "_dispatch_tool_call" + wrapper = staticmethod(_wrap_tool_dispatch) diff --git a/py/src/braintrust/integrations/cursor_sdk/test_cursor_sdk.py b/py/src/braintrust/integrations/cursor_sdk/test_cursor_sdk.py new file mode 100644 index 00000000..ce48a679 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/test_cursor_sdk.py @@ -0,0 +1,483 @@ +"""Cassette-backed tests for Cursor SDK instrumentation.""" + +# pylint: disable=import-error + +import base64 +import os +from pathlib import Path + +import pytest +import requests +from braintrust import Attachment, logger +from braintrust.integrations.anthropic import AnthropicIntegration +from braintrust.integrations.cursor_sdk import CursorSDKIntegration, setup_cursor_sdk +from braintrust.integrations.cursor_sdk._test_vcr import cursor_vcr_config +from braintrust.integrations.openai import OpenAIIntegration +from braintrust.integrations.test_utils import verify_autoinstrument_script +from braintrust.span_types import SpanTypeAttribute +from braintrust.test_helpers import find_spans_by_type, init_test_logger + + +PROJECT_NAME = "test-cursor-sdk" +TEST_MODEL = "composer-2.5" + + +@pytest.fixture +def memory_logger(): + init_test_logger(PROJECT_NAME) + with logger._internal_with_memory_background_logger() as background_logger: + yield background_logger + + +def _api_key() -> str: + return os.environ.get("CURSOR_API_KEY", "crsr_test_key_for_cassette_playback") + + +def _workspace(tmp_path: Path) -> Path: + (tmp_path / "README.md").write_text("This is a tiny cassette characterization workspace.\n", encoding="utf-8") + return tmp_path + + +@pytest.fixture(scope="module") +def vcr_config(): + return cursor_vcr_config() + + +def _call_custom_tool(client, agent_id: str, tool_name: str, call_id: str, args: dict): + """Invoke a custom tool the way Cursor's bridge does. + + The bridge reaches the SDK by POSTing a Connect request to the loopback + callback server it was handed at launch, so this posts the same request to + the same server rather than standing anything in for it. + """ + endpoint = client._owned_bridge._tool_callback_server.endpoint + response = requests.post( + f"{endpoint.url.rstrip('/')}/sdk.v1.SdkCustomToolCallbackService/CallCustomTool", + json={"agentId": agent_id, "toolName": tool_name, "toolCallId": call_id, "args": args}, + headers={ + "Authorization": f"Bearer {endpoint.auth_token}", + "Connect-Protocol-Version": "1", + }, + timeout=30, + ) + response.raise_for_status() + return response.json() + + +def test_setup_cursor_sdk_is_idempotent(): + assert setup_cursor_sdk(project=PROJECT_NAME) + assert setup_cursor_sdk(project=PROJECT_NAME) + + +@pytest.mark.vcr +def test_auto_instrument_cursor_sdk_subprocess(): + verify_autoinstrument_script("test_auto_cursor_sdk.py", timeout=45) + + +@pytest.mark.vcr +def test_characterize_no_downstream_provider_spans(memory_logger, tmp_path): + """Cursor's bridge owns provider calls, so no Python provider LLM leaf exists.""" + import cursor_sdk + + assert OpenAIIntegration.setup() + assert AnthropicIntegration.setup() + + workspace = _workspace(tmp_path) + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + with cursor_sdk.Agent.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + client=client, + ) as agent: + result = agent.send("Reply with exactly: cursor characterization complete").wait() + + assert result.status == "finished" + assert "cursor characterization complete" in result.result.lower() + spans = memory_logger.pop() + origins = {span["context"]["span_origin"]["instrumentation"]["name"] for span in spans} + assert origins == {"cursor-sdk-auto"} + assert len(find_spans_by_type(spans, SpanTypeAttribute.LLM)) == 1 + + +@pytest.mark.vcr +def test_sync_wait_traces_cursor_owned_model_turn(memory_logger, tmp_path): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + with cursor_sdk.Agent.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + client=client, + ) as agent: + result = agent.send("Reply with exactly: cursor tracing complete").wait() + + assert result.status == "finished" + spans = memory_logger.pop() + task_spans = find_spans_by_type(spans, SpanTypeAttribute.TASK) + llm_spans = find_spans_by_type(spans, SpanTypeAttribute.LLM) + assert len(task_spans) == 1 + assert len(llm_spans) == 1 + + task_span = task_spans[0] + llm_span = llm_spans[0] + assert task_span["span_attributes"]["name"] == "Cursor Agent" + assert task_span["input"] == [{"role": "user", "content": "Reply with exactly: cursor tracing complete"}] + assert task_span["output"] == result.result + assert llm_span["span_attributes"]["name"] == "Cursor Model Turn" + assert llm_span["span_parents"] == [task_span["span_id"]] + assert llm_span["metadata"] == {"model": TEST_MODEL, "provider": "cursor"} + assert llm_span["input"] == task_span["input"] + assert llm_span["output"][-1]["message"]["content"] == result.result + assert llm_span["output"][-1]["finish_reason"] == "stop" + + for span in spans: + assert span["context"]["span_origin"]["instrumentation"]["name"] == "cursor-sdk-auto" + for metric in ("prompt_tokens", "completion_tokens", "tokens", "prompt_cached_tokens"): + assert llm_span["metrics"][metric] >= 0 + assert task_span["metrics"][metric] == llm_span["metrics"][metric] + assert llm_span["metrics"]["tokens"] == ( + llm_span["metrics"]["prompt_tokens"] + llm_span["metrics"]["completion_tokens"] + ) + assert llm_span["metrics"]["time_to_first_token"] >= 0 + assert set(llm_span.get("metadata", {})) == {"model", "provider"} + allowed_metrics = { + "start", + "end", + "tokens", + "prompt_tokens", + "completion_tokens", + "time_to_first_token", + "completion_reasoning_tokens", + "prompt_cached_tokens", + "prompt_cache_creation_tokens", + } + assert set(llm_span.get("metrics", {})) <= allowed_metrics + assert set(task_span.get("metrics", {})) <= allowed_metrics + + +@pytest.mark.parametrize("consumer", ["messages", "stream", "events", "iteration", "iter_text", "text"]) +@pytest.mark.vcr +def test_sync_consumption_paths_finalize_once(memory_logger, tmp_path, consumer): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + with client.agents.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ) as agent: + run = agent.send("Reply with exactly: cursor tracing complete") + if consumer == "messages": + consumed = list(run.messages()) + elif consumer == "stream": + consumed = list(run.stream()) + elif consumer == "events": + consumed = list(run.events()) + elif consumer == "iteration": + consumed = list(run) + elif consumer == "iter_text": + consumed = list(run.iter_text()) + else: + consumed = run.text() + result = run.wait() + + assert consumed + assert result.status == "finished" + spans = memory_logger.pop() + assert len(find_spans_by_type(spans, SpanTypeAttribute.TASK)) == 1 + assert len(find_spans_by_type(spans, SpanTypeAttribute.LLM)) == 1 + + +@pytest.mark.vcr +def test_agent_prompt_one_shot(memory_logger, tmp_path): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + result = cursor_sdk.Agent.prompt( + "Reply with exactly: cursor tracing complete", + cursor_sdk.AgentOptions( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ), + client=client, + ) + + assert result.status == "finished" + spans = memory_logger.pop() + assert len(find_spans_by_type(spans, SpanTypeAttribute.TASK)) == 1 + assert len(find_spans_by_type(spans, SpanTypeAttribute.LLM)) == 1 + + +@pytest.mark.vcr +def test_resume_send_observe_finalizes_trace(memory_logger, tmp_path): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + agent = client.agents.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ) + agent_id = agent.agent_id + first_result = agent.send("Reply with exactly: cursor initial tracing complete").wait() + assert first_result.status == "finished" + agent.close() + with client.agents.resume( + agent_id, + cursor_sdk.AgentOptions( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ), + ) as resumed: + run = resumed.send("Reply with exactly: cursor resumed tracing complete") + observed = list(run.observe()) + + assert any(event.result_is_full for event in observed) + spans = memory_logger.pop() + task_spans = find_spans_by_type(spans, SpanTypeAttribute.TASK) + llm_spans = find_spans_by_type(spans, SpanTypeAttribute.LLM) + assert len(task_spans) == 2 + # observe() returns only the terminal envelope when attached after send; + # Cursor does not replay model-turn messages on that stream, so the + # observed run correctly remains a task rather than a token-less LLM. + assert len(llm_spans) == 1 + assert {span.get("output") for span in task_spans} == { + "cursor initial tracing complete", + "cursor resumed tracing complete", + } + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_async_messages_preserve_callbacks_and_trace(memory_logger, tmp_path): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + deltas = [] + steps = [] + + async def on_delta(update): + deltas.append(update) + + async with await cursor_sdk.AsyncClient.launch_bridge(workspace=str(workspace)) as client: + async with await client.agents.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ) as agent: + run = await agent.send( + "Reply with exactly: cursor async tracing complete", + cursor_sdk.SendOptions(on_delta=on_delta, on_step=steps.append), + ) + messages = [message async for message in run.messages()] + result = await run.wait() + + assert result.status == "finished" + assert any(message.type == "assistant" for message in messages) + assert deltas + assert steps + spans = memory_logger.pop() + (task_span,) = find_spans_by_type(spans, SpanTypeAttribute.TASK) + (llm_span,) = find_spans_by_type(spans, SpanTypeAttribute.LLM) + assert task_span["output"] == result.result + assert llm_span["output"][-1]["message"]["content"] == result.result + assert llm_span["span_parents"] == [task_span["span_id"]] + assert all(span["context"]["span_origin"]["instrumentation"]["name"] == "cursor-sdk-auto" for span in spans) + + +@pytest.mark.parametrize("consumer", ["stream", "events", "iteration", "iter_text", "text"]) +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_async_consumption_paths_finalize_once(memory_logger, tmp_path, consumer): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + + async def on_delta(_update): + return None + + async with await cursor_sdk.AsyncClient.launch_bridge(workspace=str(workspace)) as client: + async with await client.agents.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ) as agent: + run = await agent.send( + "Reply with exactly: cursor async tracing complete", + cursor_sdk.SendOptions(on_delta=on_delta, on_step=lambda _step: None), + ) + if consumer == "stream": + consumed = [item async for item in run.stream()] + elif consumer == "events": + consumed = [item async for item in run.events()] + elif consumer == "iteration": + consumed = [item async for item in run] + elif consumer == "iter_text": + consumed = [item async for item in run.iter_text()] + else: + consumed = await run.text() + result = await run.wait() + + assert consumed + assert result.status == "finished" + spans = memory_logger.pop() + assert len(find_spans_by_type(spans, SpanTypeAttribute.TASK)) == 1 + assert len(find_spans_by_type(spans, SpanTypeAttribute.LLM)) == 1 + + +@pytest.mark.vcr +def test_send_error_propagates_and_logs_parent_error(memory_logger, tmp_path): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + with client.agents.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ) as agent: + with pytest.raises(cursor_sdk.CursorAgentError) as raised: + agent.send( + "This request must fail before execution.", + cursor_sdk.SendOptions(model="braintrust-invalid-cursor-model"), + ) + + assert raised.value is not None + spans = memory_logger.pop() + assert len(spans) == 1 + assert spans[0]["span_attributes"]["type"] == SpanTypeAttribute.TASK + assert spans[0].get("error") + + +@pytest.mark.vcr +def test_multimodal_input_materializes_attachment(memory_logger, tmp_path): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + png = base64.b64decode( + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=" + ) + message = cursor_sdk.UserMessage( + text="Briefly describe this image.", + images=[cursor_sdk.SDKImage.from_data(png, "image/png")], + ) + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + with client.agents.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ) as agent: + result = agent.send(message).wait() + + assert result.status == "finished" + spans = memory_logger.pop() + (task_span,) = find_spans_by_type(spans, SpanTypeAttribute.TASK) + image_url = task_span["input"][0]["content"][1]["image_url"]["url"] + assert isinstance(image_url, Attachment) + assert image_url.reference["type"] == "braintrust_attachment" + assert image_url.reference["content_type"] == "image/png" + assert image_url.reference["filename"] == "image.png" + + +@pytest.mark.vcr +def test_custom_tool_dispatch_traces_under_the_agents_run(memory_logger, tmp_path): + """Cursor calls custom tools by POSTing into the SDK's loopback callback server. + + That request carries only an agent id -- no run, no agent -- so it is the + one lookup the dispatch hook cannot answer from its arguments. The spans it + opens are asserted on directly because they are created on the callback + server's handler thread, and ``memory_logger`` only overrides the + background logger for the thread that installed it. + """ + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + executed = {} + + def lookup(args, context): + executed["args"] = dict(args) + executed["call_id"] = context.tool_call_id + executed["span"] = logger.current_span() + return "cursor-custom-tool-complete" + + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + with client.agents.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ) as agent: + # Register through the SDK's own registrar rather than via + # `LocalAgentOptions(custom_tools=...)`: declaring tools up front + # makes the client mint a random agent id, which never replays. + client._owned_bridge.register_custom_tools( + agent.agent_id, {"lookup": cursor_sdk.CustomTool(execute=lookup)} + ) + run = agent.send("Reply with exactly: cursor tracing complete") + response = _call_custom_tool(client, agent.agent_id, "lookup", "call-1", {"query": "braintrust"}) + result = run.wait() + + assert result.status == "finished" + assert response["result"]["content"][0]["text"] == "cursor-custom-tool-complete" + assert executed["args"] == {"query": "braintrust"} + assert executed["call_id"] == "call-1" + + spans = memory_logger.pop() + (task_span,) = find_spans_by_type(spans, SpanTypeAttribute.TASK) + tool_span = executed["span"] + # A no-op span here means the dispatch never resolved the agent id back to + # the run's tracker, or the tool span was not made current for the callback. + assert tool_span is not logger.NOOP_SPAN + assert tool_span.root_span_id == task_span["root_span_id"] + # Nested under the run's model turn rather than opened as its own root. + assert tool_span.span_parents + assert task_span["span_id"] not in tool_span.span_parents + + +@pytest.mark.vcr +def test_builtin_tool_events_create_one_tool_span(memory_logger, tmp_path): + import cursor_sdk + + assert CursorSDKIntegration.setup() + workspace = _workspace(tmp_path) + with cursor_sdk.CursorClient.launch_bridge(workspace=str(workspace)) as client: + with client.agents.create( + model=TEST_MODEL, + api_key=_api_key(), + local=cursor_sdk.LocalAgentOptions(cwd=str(workspace)), + ) as agent: + result = agent.send( + "Use the shell tool to run `printf cursor-tool-complete`, then reply with the output." + ).wait() + + assert result.status == "finished" + spans = memory_logger.pop() + (task_span,) = find_spans_by_type(spans, SpanTypeAttribute.TASK) + llm_spans = find_spans_by_type(spans, SpanTypeAttribute.LLM) + tool_spans = find_spans_by_type(spans, SpanTypeAttribute.TOOL) + assert llm_spans + assert tool_spans + assert len({span["span_id"] for span in tool_spans}) == len(tool_spans) + llm_ids = {span["span_id"] for span in llm_spans} + for tool_span in tool_spans: + assert tool_span["input"] is not None + assert tool_span.get("output") is not None + assert any(parent in llm_ids for parent in tool_span["span_parents"]) + assert tool_span["root_span_id"] == task_span["root_span_id"] + assert tool_span["context"]["span_origin"]["instrumentation"]["name"] == "cursor-sdk-auto" diff --git a/py/src/braintrust/integrations/cursor_sdk/tracing.py b/py/src/braintrust/integrations/cursor_sdk/tracing.py new file mode 100644 index 00000000..102ca0f7 --- /dev/null +++ b/py/src/braintrust/integrations/cursor_sdk/tracing.py @@ -0,0 +1,598 @@ +"""Tracing lifecycle helpers for the Cursor Python SDK.""" + +import contextvars +import dataclasses +import json +import time +import weakref +from collections.abc import Callable, Mapping +from typing import Any + +from braintrust.integrations.utils import ( + _camel_to_snake, + _is_supported_metric_value, + _log_and_end_span, + _materialize_attachment, + _try_to_dict, +) +from braintrust.logger import start_span as _bt_start_span +from braintrust.span_types import SpanTypeAttribute + + +_INSTRUMENTATION = "cursor-sdk-auto" +# Cursor spells terminal failure statuses both bare ("error") and as wire enum +# reprs ("RUN_LIFECYCLE_STATUS_ERROR"), so match on the suffix. +_ERROR_STATUS_SUFFIXES = ("cancelled", "expired", "error") +# `Run.__init__` primes the event stream, so `_handle_event` can fire before +# `send()` hands back the run we would otherwise hang the tracker off. +_PENDING_TRACKER: contextvars.ContextVar[Any] = contextvars.ContextVar("braintrust_cursor_tracker", default=None) +# Cursor dispatches custom tools on a loopback HTTP thread that receives only an +# agent id -- no run, no agent, and a fresh context -- so that one lookup cannot +# be answered from the call itself. Holding the agent weakly keeps this from +# growing without bound; a caller that drops its agent mid-run loses custom-tool +# attribution but keeps the run trace, which is finished off the run itself. +# Every access below is a single dict/set operation, so no lock is needed. +_AGENTS_BY_ID: "weakref.WeakValueDictionary[str, Any]" = weakref.WeakValueDictionary() +_AGENT_TRACKERS_ATTR = "_braintrust_cursor_trackers" + + +def _agent_trackers(agent: Any) -> set[Any]: + """Return the agent's live tracker set, creating it on first send. + + The set lives on the agent so it is collected with it, and `setdefault` on + the instance dict keeps concurrent first sends from racing. + """ + return agent.__dict__.setdefault(_AGENT_TRACKERS_ATTR, set()) + + +def start_span(*args: Any, **kwargs: Any) -> Any: + internal = dict(kwargs.get("internal") or {}) + internal.setdefault("instrumentation", _INSTRUMENTATION) + kwargs["internal"] = internal + return _bt_start_span(*args, **kwargs) + + +def _value(obj: Any, name: str, default: Any = None) -> Any: + # `dict` first: this runs several times per streamed delta, and the + # `Mapping` ABC check is markedly slower than the concrete type check. + if isinstance(obj, dict): + return obj.get(name, default) + if isinstance(obj, Mapping): + return obj.get(name, default) + return getattr(obj, name, default) + + +def _model_id(value: Any) -> str | None: + if isinstance(value, str): + return value + model_id = _value(value, "id") + return str(model_id) if model_id else None + + +def _send_model(instance: Any, args: Any, kwargs: Any) -> str | None: + options = args[1] if len(args) > 1 else kwargs.get("options") + override = _value(options, "model") + return _model_id(override) or _model_id(getattr(instance, "model", None)) + + +def _image_part(image: Any) -> dict[str, Any] | None: + url = _value(image, "url") + if isinstance(url, str) and url: + return {"type": "image_url", "image_url": {"url": url}} + + data = _value(image, "data") + mime_type = _value(image, "mime_type") or _value(image, "mimeType") + if data is None or not isinstance(mime_type, str) or not mime_type: + return None + resolved = _materialize_attachment(data, mime_type=mime_type, label="image") + if resolved is None: + return {"type": "image_url", "image_url": {"url": data}} + return {"type": "image_url", **resolved.multimodal_part_payload} + + +def _normalize_input(message: Any) -> list[dict[str, Any]]: + if isinstance(message, str): + return [{"role": "user", "content": message}] + + text = _value(message, "text", "") + images = _value(message, "images") or () + parts: list[dict[str, Any]] = [] + if isinstance(text, str) and text: + parts.append({"type": "text", "text": text}) + for image in images: + part = _image_part(image) + if part is not None: + parts.append(part) + if parts: + return [{"role": "user", "content": parts}] + # Keep unknown SDK values intact; Braintrust serializes them at log/export time. + return [{"role": "user", "content": message}] + + +def _content_blocks(message: Any) -> Any: + content = _value(_value(message, "message"), "content", ()) + return content if isinstance(content, (list, tuple)) else () + + +def _non_negative_int(value: Any) -> int | None: + if not _is_supported_metric_value(value): + return None + result = int(value) + return result if result >= 0 else None + + +def _usage_fields(usage: Any) -> dict[str, Any]: + """Return usage as a snake_case dict; Cursor reports either casing.""" + payload = _try_to_dict(usage) + if not isinstance(payload, dict): + return {} + return {_camel_to_snake(str(name)): value for name, value in payload.items()} + + +def _usage_metrics(usage: Any) -> dict[str, int]: + fields = _usage_fields(usage) + input_tokens = _non_negative_int(fields.get("input_tokens")) + output_tokens = _non_negative_int(fields.get("output_tokens")) + cache_read = _non_negative_int(fields.get("cache_read_tokens")) + cache_write = _non_negative_int(fields.get("cache_write_tokens")) + reasoning = _non_negative_int(fields.get("reasoning_tokens")) + + metrics: dict[str, int] = {} + prompt_parts = [value for value in (input_tokens, cache_read, cache_write) if value is not None] + prompt_tokens = sum(prompt_parts) if prompt_parts else None + if prompt_tokens is not None: + metrics["prompt_tokens"] = prompt_tokens + if output_tokens is not None: + metrics["completion_tokens"] = output_tokens + if prompt_tokens is not None and output_tokens is not None: + metrics["tokens"] = prompt_tokens + output_tokens + if cache_read is not None: + metrics["prompt_cached_tokens"] = cache_read + if cache_write is not None: + metrics["prompt_cache_creation_tokens"] = cache_write + if reasoning is not None: + metrics["completion_reasoning_tokens"] = reasoning + return metrics + + +def _canonical_tool_call(call_id: str, name: str, args: Any) -> dict[str, Any]: + if isinstance(args, str): + arguments = args + else: + try: + # OpenAI's canonical tool-call shape specifically requires a JSON string. + arguments = json.dumps(args) + except (TypeError, ValueError): + arguments = str(args) + return { + "id": call_id, + "type": "function", + "function": {"name": name, "arguments": arguments}, + } + + +@dataclasses.dataclass +class _ToolState: + span: Any + completed: bool = False + + def finish(self, *, output: Any = None, error: Any = None) -> None: + if self.completed: + return + event: dict[str, Any] = {} + if output is not None: + event["output"] = output + if error is not None: + event["error"] = error + if event: + self.span.log(**event) + self.span.end() + self.completed = True + + +class CursorRunTracker: + """Own one Cursor parent run and its model/tool child spans.""" + + def __init__(self, *, message: Any, model: str | None) -> None: + self.start_time = time.time() + self.model = model + self.history = _normalize_input(message) + self.root_span = start_span( + name="Cursor Agent", + span_attributes={"type": SpanTypeAttribute.TASK}, + input=list(self.history), + start_time=self.start_time, + set_current=False, + ) + self.root_export = self.root_span.export() + self.run: Any = None + self.agent_trackers: set[Any] = set() + self.llm_span: Any = None + self.llm_text = "" + self.reasoning_text = "" + self.llm_tool_calls: list[dict[str, Any]] = [] + self.llm_start = self.start_time + self.turn_ttft = 0.0 + self.turn_count = 0 + self.tools: dict[str, _ToolState] = {} + self.aggregate_metrics: dict[str, int] = {} + # `observe()` is a second, independent stream over the same run, so an + # observed run can redeliver events already seen via `_apply_event_state`. + self.seen_events: set[tuple[Any, Any]] = set() + self.finished = False + + def _update_model(self, candidate: Any) -> None: + resolved = _model_id(candidate) + if resolved: + self.model = resolved + + def attach(self, run: Any, agent: Any) -> None: + self.run = run + setattr(run, "_braintrust_cursor_tracker", self) + self._update_model(getattr(run, "model", None)) + self.agent_trackers = _agent_trackers(agent) + self.agent_trackers.add(self) + agent_id = str(getattr(run, "agent_id", "") or "") + if agent_id: + _AGENTS_BY_ID[agent_id] = agent + # Nothing to replay: the run primes its stream inside `send()`, so any + # event it has already buffered reached the tracker through + # `_apply_event_state` while `_PENDING_TRACKER` was still set. + + def _start_llm(self, now: float) -> None: + if self.llm_span is not None: + return + # The first turn is anchored to the send so its duration covers the + # queueing latency Cursor spends before streaming any tokens. + self.llm_start = self.start_time if self.turn_count == 0 else now + self.turn_ttft = max(0.0, now - self.llm_start) + self.llm_span = start_span( + name="Cursor Model Turn", + span_attributes={"type": SpanTypeAttribute.LLM}, + input=list(self.history), + metadata={"model": self.model or "unknown", "provider": "cursor"}, + parent=self.root_export, + start_time=self.llm_start, + set_current=False, + ) + + def _assistant_message(self, *, include_reasoning: bool) -> dict[str, Any]: + message: dict[str, Any] = {"role": "assistant", "content": self.llm_text or None} + if self.llm_tool_calls: + message["tool_calls"] = list(self.llm_tool_calls) + if include_reasoning and self.reasoning_text: + message["reasoning"] = self.reasoning_text + return message + + def _llm_output(self) -> list[dict[str, Any]]: + output: list[dict[str, Any]] = [] + if self.reasoning_text: + output.append( + { + "type": "reasoning", + "summary": [{"type": "summary_text", "text": self.reasoning_text}], + } + ) + output.append( + { + "index": 0, + "finish_reason": "tool_calls" if self.llm_tool_calls else "stop", + "message": self._assistant_message(include_reasoning=False), + } + ) + return output + + def _finish_llm(self, usage: Any = None) -> None: + if self.llm_span is None: + return + metrics: dict[str, Any] = dict(_usage_metrics(usage)) + for key, value in metrics.items(): + self.aggregate_metrics[key] = self.aggregate_metrics.get(key, 0) + value + metrics["time_to_first_token"] = self.turn_ttft + _log_and_end_span( + self.llm_span, + output=self._llm_output(), + metrics=metrics, + metadata={"model": self.model, "provider": "cursor"} if self.model else None, + ) + + self.history.append(self._assistant_message(include_reasoning=True)) + self.llm_span = None + self.llm_text = "" + self.reasoning_text = "" + self.llm_tool_calls = [] + self.turn_count += 1 + + def start_tool(self, call_id: str, name: str, args: Any) -> _ToolState: + existing = self.tools.get(call_id) + if existing is not None: + return existing + self._start_llm(time.time()) + parent = self.llm_span.export() if self.llm_span is not None else self.root_export + tool_name = name or "tool" + # Not `set_current=False`: that fixes `can_set_current` off for the + # span's lifetime, and `_wrap_tool_dispatch` makes this span current + # later so a custom tool's own spans nest under it. + span = start_span( + name=tool_name, + span_attributes={"type": SpanTypeAttribute.TOOL}, + input=args, + parent=parent, + ) + span.unset_current() + state = _ToolState(span=span) + self.tools[call_id] = state + self.llm_tool_calls.append(_canonical_tool_call(call_id, tool_name, args)) + return state + + def _finish_tool(self, call_id: str, *, output: Any, is_error: bool) -> None: + state = self.tools.get(call_id) + if state is None: + state = self.start_tool(call_id, "tool", None) + state.finish(output=output, error=str(output) if is_error else None) + self.history.append({"role": "tool", "tool_call_id": call_id, "content": output}) + + def add_event(self, event: Any, run: Any) -> None: + if self.finished: + return + offset = getattr(event, "offset", None) + if offset is not None: + event_key = (getattr(event, "kind", ""), offset) + if event_key in self.seen_events: + return + self.seen_events.add(event_key) + message = getattr(event, "sdk_message", None) + message_type = _value(message, "type", "") + if message_type == "thinking": + self._start_llm(time.time()) + text = _value(message, "text", "") + if isinstance(text, str): + self.reasoning_text += text + elif message_type == "assistant": + self._start_llm(time.time()) + for block in _content_blocks(message): + block_type = _value(block, "type") + if block_type == "text": + text = _value(block, "text", "") + if isinstance(text, str): + self.llm_text += text + elif block_type == "tool_use": + self.start_tool( + str(_value(block, "id", "")), + str(_value(block, "name", "tool")), + _value(block, "input"), + ) + elif message_type == "tool_call": + call_id = str(_value(message, "call_id", "")) + status = str(_value(message, "status", "")) + if status == "running": + self.start_tool(call_id, str(_value(message, "name", "tool")), _value(message, "args")) + elif status in {"completed", "error"}: + self._finish_tool(call_id, output=_value(message, "result"), is_error=status == "error") + elif message_type == "usage": + self._finish_llm(_value(message, "usage")) + + if run is not None: + self._update_model(getattr(run, "model", None)) + if getattr(event, "result_is_full", False): + result = getattr(event, "result", None) + self._update_model(_value(result, "model")) + self.finish(run, result=result) + + def finish(self, run: Any = None, *, result: Any = None, cancelled: bool = False) -> None: + if self.finished: + return + self._finish_llm() + for state in self.tools.values(): + if not state.completed: + state.finish(error="Cursor run cancelled" if cancelled else None) + + target = run or self.run + output = getattr(target, "result", None) or _value(result, "result") + usage = getattr(target, "usage", None) or _value(result, "usage") + metrics = _usage_metrics(usage) if usage is not None else dict(self.aggregate_metrics) + event: dict[str, Any] = {} + if output: + event["output"] = output + if metrics: + event["metrics"] = metrics + status = str(_value(result, "status") or getattr(target, "status", "")).lower() + if cancelled or status.endswith(_ERROR_STATUS_SUFFIXES): + event["error"] = f"Cursor run {('cancelled' if cancelled else status)}" + if event: + self.root_span.log(**event) + self.root_span.end() + self.finished = True + self.agent_trackers.discard(self) + + def fail(self, error: BaseException) -> None: + if self.finished: + return + self.root_span.log(error=error) + self.finish() + + +def _tracker_for_run(run: Any) -> CursorRunTracker | None: + tracker = getattr(run, "_braintrust_cursor_tracker", None) + if tracker is None: + tracker = _PENDING_TRACKER.get() + return tracker + + +def _wrap_sync_send(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + message = args[0] if args else kwargs.get("message") + tracker = CursorRunTracker(message=message, model=_send_model(instance, args, kwargs)) + token = _PENDING_TRACKER.set(tracker) + try: + run = wrapped(*args, **kwargs) + except Exception as error: + tracker.fail(error) + raise + finally: + _PENDING_TRACKER.reset(token) + tracker.attach(run, instance) + return run + + +async def _wrap_async_send(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + message = args[0] if args else kwargs.get("message") + tracker = CursorRunTracker(message=message, model=_send_model(instance, args, kwargs)) + token = _PENDING_TRACKER.set(tracker) + try: + run = await wrapped(*args, **kwargs) + except Exception as error: + tracker.fail(error) + raise + finally: + _PENDING_TRACKER.reset(token) + tracker.attach(run, instance) + return run + + +def _run_lifecycle_hooks( + post: Callable[[Any, Any, Any, Any], None], + *, + fail_on_error: bool = True, +) -> tuple[Any, Any]: + """Build the ``(sync, async)`` wrapper pair for one Run lifecycle method. + + Cursor mirrors every ``Run`` method on ``AsyncRun``, so the two halves + differ only by ``await``. Generating them together keeps the tracker + protocol in one place instead of one copy per flavor. + """ + + def sync_wrapper(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + tracker = _tracker_for_run(instance) + try: + result = wrapped(*args, **kwargs) + except Exception as error: + if fail_on_error and tracker is not None: + tracker.fail(error) + raise + if tracker is not None: + post(tracker, instance, args, kwargs) + return result + + async def async_wrapper(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + tracker = _tracker_for_run(instance) + try: + result = await wrapped(*args, **kwargs) + except Exception as error: + if fail_on_error and tracker is not None: + tracker.fail(error) + raise + if tracker is not None: + post(tracker, instance, args, kwargs) + return result + + return sync_wrapper, async_wrapper + + +def _wrap_apply_event_state(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + """Trace one stream event. + + `Run` and `AsyncRun` both funnel every event through this one synchronous + base method -- it is where all the state the tracker reads is applied -- so + a single wrapper covers both flavors and every consumption path. + """ + tracker = _tracker_for_run(instance) + try: + result = wrapped(*args, **kwargs) + except Exception as error: + if tracker is not None: + tracker.fail(error) + raise + if tracker is not None: + tracker.add_event(args[0] if args else kwargs.get("event"), instance) + return result + + +_wrap_sync_wait, _wrap_async_wait = _run_lifecycle_hooks( + lambda tracker, instance, args, kwargs: tracker.finish(instance) +) +# `cancel()` failing is not a run failure, so it does not fail the trace. +_wrap_sync_cancel, _wrap_async_cancel = _run_lifecycle_hooks( + lambda tracker, instance, args, kwargs: tracker.finish(instance, cancelled=True), + fail_on_error=False, +) + + +def _wrap_sync_observe(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + stream = wrapped(*args, **kwargs) + tracker = _tracker_for_run(instance) + + def traced_stream(): + try: + for event in stream: + if tracker is not None: + tracker.add_event(event, instance) + yield event + except Exception as error: + if tracker is not None: + tracker.fail(error) + raise + + return traced_stream() + + +def _wrap_async_observe(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + stream = wrapped(*args, **kwargs) + tracker = _tracker_for_run(instance) + + async def traced_stream(): + try: + async for event in stream: + if tracker is not None: + tracker.add_event(event, instance) + yield event + except Exception as error: + if tracker is not None: + tracker.fail(error) + raise + + return traced_stream() + + +def _finish_agent_trackers(instance: Any) -> None: + for tracker in list(getattr(instance, _AGENT_TRACKERS_ATTR, ())): + status = str(getattr(tracker.run, "status", "")).lower() + # A run still in flight when its agent closes is abandoned, not done. + tracker.finish( + tracker.run, + cancelled=not status.endswith(("finished", *_ERROR_STATUS_SUFFIXES)), + ) + + +def _wrap_sync_close(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + try: + return wrapped(*args, **kwargs) + finally: + _finish_agent_trackers(instance) + + +async def _wrap_async_close(wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: + try: + return await wrapped(*args, **kwargs) + finally: + _finish_agent_trackers(instance) + + +def _wrap_tool_dispatch(wrapped: Any, _instance: Any, args: Any, kwargs: Any) -> Any: + request = args[2] if len(args) > 2 else kwargs.get("request", {}) + agent_id = str(_value(request, "agentId", _value(request, "agent_id", ""))) + call_id = str(_value(request, "toolCallId", _value(request, "tool_call_id", ""))) + name = str(_value(request, "toolName", _value(request, "tool_name", "tool"))) + tool_args = _value(request, "args", {}) + agent = _AGENTS_BY_ID.get(agent_id) + trackers = getattr(agent, _AGENT_TRACKERS_ATTR, ()) if agent is not None else () + tracker = next(iter(trackers), None) + if tracker is None: + return wrapped(*args, **kwargs) + # `start_tool` returns the existing state when the run already opened a + # span for this call, so it doubles as the lookup. + state = tracker.start_tool(call_id, name, tool_args) + state.span.set_current() + try: + return wrapped(*args, **kwargs) + finally: + state.span.unset_current() diff --git a/py/src/braintrust/integrations/test_utils.py b/py/src/braintrust/integrations/test_utils.py index 99d0d16b..181d4c7d 100644 --- a/py/src/braintrust/integrations/test_utils.py +++ b/py/src/braintrust/integrations/test_utils.py @@ -50,6 +50,7 @@ def autoinstrument_test_context( integration: str | None = None, use_vcr: bool = True, cassettes_dir: Path | None = None, + vcr_config: dict | None = None, ): """Context manager for auto_instrument tests. @@ -64,6 +65,9 @@ def autoinstrument_test_context( Use ``cassettes_dir`` to override with an explicit path (takes precedence over ``integration``). + Use ``vcr_config`` for providers that need request scrubbing or matching + beyond :func:`get_vcr_config`, such as the Cursor SDK's loopback bridge. + Use ``use_vcr=False`` for tests that replay provider traffic through a non-VCR mechanism, such as the Claude Agent SDK subprocess cassette transport. @@ -87,7 +91,7 @@ def autoinstrument_test_context( yield memory_logger return - my_vcr = vcr.VCR(**get_vcr_config()) + my_vcr = vcr.VCR(**(vcr_config if vcr_config is not None else get_vcr_config())) with my_vcr.use_cassette(str(cassette_path)): yield memory_logger From 8e8ea322268bfeb8c294cd18fefa60c7229b83cb Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 7 Aug 2026 09:57:17 -0400 Subject: [PATCH 2/3] test(cursor_sdk): skip broken sync bridge on Windows The upstream sync bridge calls os.get_blocking(), which is unavailable on Windows. Keep running the async integration coverage there while skipping only tests that require CursorClient.launch_bridge(). --- .../integrations/cursor_sdk/test_cursor_sdk.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/py/src/braintrust/integrations/cursor_sdk/test_cursor_sdk.py b/py/src/braintrust/integrations/cursor_sdk/test_cursor_sdk.py index ce48a679..040c1e28 100644 --- a/py/src/braintrust/integrations/cursor_sdk/test_cursor_sdk.py +++ b/py/src/braintrust/integrations/cursor_sdk/test_cursor_sdk.py @@ -20,6 +20,10 @@ PROJECT_NAME = "test-cursor-sdk" TEST_MODEL = "composer-2.5" +_REQUIRES_SYNC_BRIDGE = pytest.mark.skipif( + os.name == "nt", + reason="cursor-sdk's sync bridge uses os.get_blocking(), which is unavailable on Windows", +) @pytest.fixture @@ -69,11 +73,13 @@ def test_setup_cursor_sdk_is_idempotent(): assert setup_cursor_sdk(project=PROJECT_NAME) +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_auto_instrument_cursor_sdk_subprocess(): verify_autoinstrument_script("test_auto_cursor_sdk.py", timeout=45) +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_characterize_no_downstream_provider_spans(memory_logger, tmp_path): """Cursor's bridge owns provider calls, so no Python provider LLM leaf exists.""" @@ -100,6 +106,7 @@ def test_characterize_no_downstream_provider_spans(memory_logger, tmp_path): assert len(find_spans_by_type(spans, SpanTypeAttribute.LLM)) == 1 +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_sync_wait_traces_cursor_owned_model_turn(memory_logger, tmp_path): import cursor_sdk @@ -159,6 +166,7 @@ def test_sync_wait_traces_cursor_owned_model_turn(memory_logger, tmp_path): assert set(task_span.get("metrics", {})) <= allowed_metrics +@_REQUIRES_SYNC_BRIDGE @pytest.mark.parametrize("consumer", ["messages", "stream", "events", "iteration", "iter_text", "text"]) @pytest.mark.vcr def test_sync_consumption_paths_finalize_once(memory_logger, tmp_path, consumer): @@ -194,6 +202,7 @@ def test_sync_consumption_paths_finalize_once(memory_logger, tmp_path, consumer) assert len(find_spans_by_type(spans, SpanTypeAttribute.LLM)) == 1 +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_agent_prompt_one_shot(memory_logger, tmp_path): import cursor_sdk @@ -217,6 +226,7 @@ def test_agent_prompt_one_shot(memory_logger, tmp_path): assert len(find_spans_by_type(spans, SpanTypeAttribute.LLM)) == 1 +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_resume_send_observe_finalizes_trace(memory_logger, tmp_path): import cursor_sdk @@ -339,6 +349,7 @@ async def on_delta(_update): assert len(find_spans_by_type(spans, SpanTypeAttribute.LLM)) == 1 +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_send_error_propagates_and_logs_parent_error(memory_logger, tmp_path): import cursor_sdk @@ -364,6 +375,7 @@ def test_send_error_propagates_and_logs_parent_error(memory_logger, tmp_path): assert spans[0].get("error") +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_multimodal_input_materializes_attachment(memory_logger, tmp_path): import cursor_sdk @@ -395,6 +407,7 @@ def test_multimodal_input_materializes_attachment(memory_logger, tmp_path): assert image_url.reference["filename"] == "image.png" +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_custom_tool_dispatch_traces_under_the_agents_run(memory_logger, tmp_path): """Cursor calls custom tools by POSTing into the SDK's loopback callback server. @@ -450,6 +463,7 @@ def lookup(args, context): assert task_span["span_id"] not in tool_span.span_parents +@_REQUIRES_SYNC_BRIDGE @pytest.mark.vcr def test_builtin_tool_events_create_one_tool_span(memory_logger, tmp_path): import cursor_sdk From a0bce3a00349d7d8e258dc7aa33155cecc179586 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 7 Aug 2026 10:09:27 -0400 Subject: [PATCH 3/3] ci(checks): install Python build dependencies Mise currently falls back to compiling Python 3.13 on Ubuntu. Install the development libraries required for bz2, lzma, and readline so provider sessions do not fail while importing otherwise valid dependencies. --- .github/actions/setup-python-env/action.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/actions/setup-python-env/action.yml b/.github/actions/setup-python-env/action.yml index f4132874..7d29375e 100644 --- a/.github/actions/setup-python-env/action.yml +++ b/.github/actions/setup-python-env/action.yml @@ -9,6 +9,12 @@ inputs: runs: using: "composite" steps: + - name: Install Python build dependencies + if: runner.os == 'Linux' + shell: bash + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends --yes libbz2-dev liblzma-dev libreadline-dev - name: Set up mise uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0 with: