diff --git a/py/noxfile.py b/py/noxfile.py index 1d6b1a60..3c309d57 100644 --- a/py/noxfile.py +++ b/py/noxfile.py @@ -473,6 +473,17 @@ def test_claude_agent_sdk(session, version): _run_tests(session, f"{INTEGRATION_DIR}/claude_agent_sdk/test_claude_agent_sdk.py", version=version) +ANTIGRAVITY_VERSIONS = _get_matrix_versions("google-antigravity") + + +@nox.session() +@nox.parametrize("version", ANTIGRAVITY_VERSIONS, ids=ANTIGRAVITY_VERSIONS) +def test_antigravity(session, version): + _install_test_deps(session) + _install_matrix_dep(session, "google-antigravity", version) + _run_tests(session, f"{INTEGRATION_DIR}/antigravity/test_antigravity.py", version=version) + + CURSOR_SDK_VERSIONS = _get_matrix_versions("cursor-sdk") diff --git a/py/pyproject.toml b/py/pyproject.toml index f724822c..5f0aa489 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -536,6 +536,10 @@ latest = "claude-agent-sdk==0.2.179" latest = "cursor-sdk==1.3.1" "1.0.25" = "cursor-sdk==1.0.25" +[tool.braintrust.matrix.google-antigravity] +latest = "google-antigravity==0.1.23" +"0.1.23" = "google-antigravity==0.1.23" + [tool.braintrust.matrix.agno] latest = "agno==3.1.12" "2.4.0" = "agno==2.4.0" @@ -699,6 +703,7 @@ agentscope = ["agentscope"] agno = ["agno"] autogen = ["autogen-agentchat"] anthropic = ["anthropic"] +antigravity = ["google-antigravity"] bedrock_runtime = ["boto3", "botocore"] cohere = ["cohere"] claude_agent_sdk = ["claude-agent-sdk"] @@ -741,6 +746,7 @@ crewai = "crewai" cursor-sdk = "cursor_sdk" dspy = "dspy" google-adk = "google.adk" +google-antigravity = "google.antigravity" google-genai = "google.genai" google-cloud-discoveryengine = "google.cloud.discoveryengine_v1" instructor = "instructor" diff --git a/py/src/braintrust/auto.py b/py/src/braintrust/auto.py index b0b5d2b6..08fdb522 100644 --- a/py/src/braintrust/auto.py +++ b/py/src/braintrust/auto.py @@ -47,6 +47,7 @@ def auto_instrument( agentscope: bool = True, claude_agent_sdk: bool = True, cursor_sdk: bool = True, + antigravity: bool = True, dspy: bool = True, adk: bool = True, langchain: bool = True, @@ -92,6 +93,7 @@ def auto_instrument( agentscope: Enable AgentScope instrumentation (default: True) claude_agent_sdk: Enable Claude Agent SDK instrumentation (default: True) cursor_sdk: Enable Cursor SDK instrumentation (default: True) + antigravity: Enable Google Antigravity SDK instrumentation (default: True) dspy: Enable DSPy instrumentation (default: True) adk: Enable Google ADK instrumentation (default: True) langchain: Enable LangChain instrumentation (default: True) @@ -198,6 +200,8 @@ def auto_instrument( results["claude_agent_sdk"] = _instrument_integration("claude_agent_sdk", "ClaudeAgentSDKIntegration") if cursor_sdk: results["cursor_sdk"] = _instrument_integration("cursor_sdk", "CursorSDKIntegration") + if antigravity: + results["antigravity"] = _instrument_integration("antigravity", "AntigravityIntegration") if dspy: results["dspy"] = _instrument_integration("dspy", "DSPyIntegration") if adk: diff --git a/py/src/braintrust/integrations/__init__.py b/py/src/braintrust/integrations/__init__.py index c9e81b75..9c206780 100644 --- a/py/src/braintrust/integrations/__init__.py +++ b/py/src/braintrust/integrations/__init__.py @@ -10,6 +10,7 @@ "AgnoIntegration": "agno", "AISDKIntegration": "ai_sdk", "AnthropicIntegration": "anthropic", + "AntigravityIntegration": "antigravity", "AutoGenIntegration": "autogen", "BedrockRuntimeIntegration": "bedrock_runtime", "ClaudeAgentSDKIntegration": "claude_agent_sdk", @@ -45,6 +46,7 @@ from .agno import AgnoIntegration as AgnoIntegration from .ai_sdk import AISDKIntegration as AISDKIntegration from .anthropic import AnthropicIntegration as AnthropicIntegration + from .antigravity import AntigravityIntegration as AntigravityIntegration from .autogen import AutoGenIntegration as AutoGenIntegration from .bedrock_runtime import BedrockRuntimeIntegration as BedrockRuntimeIntegration from .claude_agent_sdk import ClaudeAgentSDKIntegration as ClaudeAgentSDKIntegration @@ -79,6 +81,7 @@ "AgnoIntegration", "AISDKIntegration", "AnthropicIntegration", + "AntigravityIntegration", "AutoGenIntegration", "BedrockRuntimeIntegration", "ClaudeAgentSDKIntegration", diff --git a/py/src/braintrust/integrations/antigravity/__init__.py b/py/src/braintrust/integrations/antigravity/__init__.py new file mode 100644 index 00000000..54d2eb91 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/__init__.py @@ -0,0 +1,34 @@ +"""Braintrust tracing for the Google Antigravity SDK. + +Instrument before creating an Agent, then consume its ChatResponse normally. +""" + +from typing import Any + +from braintrust.logger import NOOP_SPAN, current_span, init_logger + +from .integration import AntigravityIntegration +from .patchers import AgentPatcher + + +__all__ = ["AntigravityIntegration", "setup_antigravity", "wrap_antigravity_agent"] + + +def setup_antigravity( + api_key: str | None = None, + project_id: str | None = None, + project: str | None = None, +) -> bool: + """Enable tracing for Antigravity chat responses.""" + if current_span() == NOOP_SPAN: + init_logger(project=project, api_key=api_key, project_id=project_id) + return AntigravityIntegration.setup() + + +def wrap_antigravity_agent(agent_class: Any) -> Any: + """Instrument the Conversation surface used by an Antigravity Agent. + + Patches in place, including Agent classes imported before this call. + """ + AntigravityIntegration.setup() + return AgentPatcher.wrap_target(agent_class) diff --git a/py/src/braintrust/integrations/antigravity/_test_transport.py b/py/src/braintrust/integrations/antigravity/_test_transport.py new file mode 100644 index 00000000..b05b4bea --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/_test_transport.py @@ -0,0 +1,148 @@ +"""Test-only record/replay for the harness WebSocket, using real SDK parsers. + +HTTP VCR cannot intercept the bundled Go runtime's Gemini requests. Record +actual WebSocket frames instead, then replay through LocalConnection's real +event processor. No provider responses are synthesized. +""" + +import asyncio +import json +import os +from contextlib import contextmanager +from pathlib import Path + +from braintrust.integrations.conftest import _versioned_cassette_dir +from google.antigravity.connections.local.event_processor import parse_initialize_response +from google.antigravity.connections.local.local_connection import LocalConnection, LocalConnectionStrategy +from google.antigravity.proto import localharness_pb2 +from google.protobuf import json_format + + +def cassette_path(name): + base = Path(os.environ.get("BRAINTRUST_INTEGRATIONS_DIR", Path(__file__).resolve().parent.parent)) + return Path(_versioned_cassette_dir(str(base / "antigravity" / "cassettes"))) / f"{name}.json" + + +def _sanitize(value): + if isinstance(value, dict): + return {k: "REDACTED" if k in ("apiKey", "api_key") else _sanitize(v) for k, v in value.items()} + if isinstance(value, list): + return [_sanitize(v) for v in value] + if isinstance(value, str): + for key in ("GEMINI_API_KEY", "GOOGLE_API_KEY"): + secret = os.environ.get(key) + if secret: + value = value.replace(secret, "REDACTED") + value = value.replace(str(Path.cwd()), "WORKSPACE") + if value.startswith(("/private/var/folders/", "/tmp/pytest-", "C:\\Users\\")): + value = "TEST_WORKSPACE" + return value + + +class _RecordingSocket: + def __init__(self, ws, frames): + self.ws, self.frames = ws, frames + + async def send(self, data): + self.frames.append({"send": _sanitize(json.loads(data))}) + await self.ws.send(data) + + async def recv(self): + data = await self.ws.recv() + self.frames.append({"recv": _sanitize(json.loads(data))}) + return data + + def __aiter__(self): + return self + + async def __anext__(self): + return await self.recv() + + async def close(self): + await self.ws.close() + + +class _ReplaySocket: + def __init__(self, frames): + self.frames = iter(frames) + self.next_frame = next(self.frames, None) + self.changed = asyncio.Event() + + def _advance(self): + self.next_frame = next(self.frames, None) + self.changed.set() + + async def send(self, data): + assert self.next_frame is not None and "send" in self.next_frame + actual = json.loads(data) + expected = self.next_frame["send"] + # Handshake has machine-specific workspace, credentials and config. + # Prompts must match exactly; other events retain their protocol type. + assert actual.keys() == expected.keys() + if "userInput" in actual: + assert actual == expected + self._advance() + + async def recv(self): + while self.next_frame is None or "recv" not in self.next_frame: + self.changed.clear() + await self.changed.wait() + data = json.dumps(self.next_frame["recv"]) + self._advance() + await asyncio.sleep(0) + return data + + def __aiter__(self): + return self + + async def __anext__(self): + return await self.recv() + + async def close(self): + pass + + +@contextmanager +def cassette_transport(name): + path = cassette_path(name) + mode = os.environ.get("BRAINTRUST_ANTIGRAVITY_RECORD_MODE", "none" if os.getenv("CI") else "once") + recording = mode == "all" or (mode == "once" and not path.exists()) + original_spawn = LocalConnectionStrategy._spawn_harness_and_connect_ws + original_enter = LocalConnectionStrategy.__aenter__ + frames = [] + + async def spawn(strategy, **kwargs): + process, ws, url = await original_spawn(strategy, **kwargs) + return process, _RecordingSocket(ws, frames), url + + async def enter(strategy): + ws = _ReplaySocket(json.loads(path.read_text(encoding="utf-8"))) + init = localharness_pb2.InitializeConversationEvent(config=strategy._build_harness_config()) # pylint: disable=no-member + await ws.send(json_format.MessageToJson(init)) + event = localharness_pb2.OutputEvent() # pylint: disable=no-member + json_format.Parse(await ws.recv(), event) + parsed = parse_initialize_response(event.initialize_conversation_response) + strategy._connection = LocalConnection( + process=None, + ws=ws, + tool_runner=strategy._tool_runner, + hook_runner=strategy._hook_runner, + initial_history=parsed.history, + initial_usage=parsed.cumulative_usage, + initial_trajectory_usages=parsed.trajectory_usages, + ) + + if recording: + LocalConnectionStrategy._spawn_harness_and_connect_ws = spawn + else: + if not path.exists(): + raise FileNotFoundError(f"Missing Antigravity recording: {path}") + LocalConnectionStrategy.__aenter__ = enter + try: + yield + finally: + LocalConnectionStrategy.__aenter__ = original_enter + LocalConnectionStrategy._spawn_harness_and_connect_ws = original_spawn + if recording: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(frames, indent=2) + "\n", encoding="utf-8") diff --git a/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/cancel.json b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/cancel.json new file mode 100644 index 00000000..b082e433 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/cancel.json @@ -0,0 +1,226 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582147645091", + "initializeConversationResponse": { + "cascadeId": "edaa2b7a92ac93ec7d863246b93571dd", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Reply with exactly: antigravity tracing complete" + } + ] + } + } + }, + { + "send": { + "haltRequest": true + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582147646508", + "trajectoryStateUpdate": { + "trajectoryId": "edaa2b7a92ac93ec7d863246b93571dd", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582147657527", + "stepUpdate": { + "cascadeId": "edaa2b7a92ac93ec7d863246b93571dd", + "trajectoryId": "edaa2b7a92ac93ec7d863246b93571dd", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Reply with exactly: antigravity tracing complete", + "thinkingDelta": "", + "text": "Reply with exactly: antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582147661036", + "trajectoryStateUpdate": { + "trajectoryId": "edaa2b7a92ac93ec7d863246b93571dd", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/chat.json b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/chat.json new file mode 100644 index 00000000..ae747863 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/chat.json @@ -0,0 +1,332 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582005876262", + "initializeConversationResponse": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Reply with exactly: antigravity tracing complete" + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582005879508", + "trajectoryStateUpdate": { + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582005889778", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Reply with exactly: antigravity tracing complete", + "thinkingDelta": "", + "text": "Reply with exactly: antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582008018830", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "antigravity tracing complete", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582008024828", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582008024961", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582008026147", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582008026147", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "usage": { + "promptTokenCount": "4213", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "5", + "thoughtsTokenCount": "56", + "totalTokenCount": "4274", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4213" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4213", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "5", + "thoughtsTokenCount": "56", + "totalTokenCount": "4274", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4213" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582008028043", + "trajectoryStateUpdate": { + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/document.json b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/document.json new file mode 100644 index 00000000..95f6ad20 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/document.json @@ -0,0 +1,412 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582465566755", + "initializeConversationResponse": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "What is the secret word in this document?" + }, + { + "media": { + "mimeType": "text/plain", + "data": "VGhlIHNlY3JldCB3b3JkIGlzIHBpbmVhcHBsZS4=" + } + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582465572784", + "trajectoryStateUpdate": { + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582465590444", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "What is the secret word in this document?", + "thinkingDelta": "", + "text": "What is the secret word in this document?" + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582470555245", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 1, + "state": "STATE_ERROR", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "errorMessage": "Denied by policy \"confirm_run_command\".", + "thinking": "", + "textDelta": "Denied by policy \"confirm_run_command\". (\"denied by pre-tool hook: Denied by policy \\\"confirm_run_command\\\".\")", + "thinkingDelta": "", + "text": "Denied by policy \"confirm_run_command\". (\"denied by pre-tool hook: Denied by policy \\\"confirm_run_command\\\".\")", + "error": { + "errorMessage": "Denied by policy \"confirm_run_command\". (\"denied by pre-tool hook: Denied by policy \\\"confirm_run_command\\\".\")", + "httpCode": 0 + } + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582470556031", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "usage": { + "promptTokenCount": "4218", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "134", + "thoughtsTokenCount": "288", + "totalTokenCount": "4640", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4218" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4218", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "134", + "thoughtsTokenCount": "288", + "totalTokenCount": "4640", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4218" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582474689291", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "The secret word is **pineapple**.", + "thinkingDelta": "", + "text": "The secret word is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582474704013", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582474704146", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582474706247", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 2, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "10", + "timestampMicros": "1794582474706247", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "usage": { + "promptTokenCount": "8927", + "cachedContentTokenCount": "2188", + "candidatesTokenCount": "141", + "thoughtsTokenCount": "602", + "totalTokenCount": "9670", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8927" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2188" + } + ] + } + } + ], + "total": { + "promptTokenCount": "8927", + "cachedContentTokenCount": "2188", + "candidatesTokenCount": "141", + "thoughtsTokenCount": "602", + "totalTokenCount": "9670", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8927" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2188" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "11", + "timestampMicros": "1794582474708301", + "trajectoryStateUpdate": { + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/multiple_turns.json b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/multiple_turns.json new file mode 100644 index 00000000..0500e0f5 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/multiple_turns.json @@ -0,0 +1,504 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582147784720", + "initializeConversationResponse": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Reply with exactly: antigravity tracing complete" + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582147786113", + "trajectoryStateUpdate": { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582147795578", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Reply with exactly: antigravity tracing complete", + "thinkingDelta": "", + "text": "Reply with exactly: antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582149691338", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "antigravity tracing complete", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582149702673", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582149702845", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582149705522", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582149705522", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "usage": { + "promptTokenCount": "4209", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "5", + "thoughtsTokenCount": "22", + "totalTokenCount": "4236", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4209" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4209", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "5", + "thoughtsTokenCount": "22", + "totalTokenCount": "4236", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4209" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582149708045", + "trajectoryStateUpdate": { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "state": "STATE_FULLY_IDLE" + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Reply with exactly: antigravity tracing complete" + } + ] + } + } + }, + { + "recv": { + "seqNum": "10", + "timestampMicros": "1794582149709032", + "trajectoryStateUpdate": { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "11", + "timestampMicros": "1794582149711998", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 2, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Reply with exactly: antigravity tracing complete", + "thinkingDelta": "", + "text": "Reply with exactly: antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "12", + "timestampMicros": "1794582151788602", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 3, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "antigravity tracing complete", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "13", + "timestampMicros": "1794582151788892", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 3, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "14", + "timestampMicros": "1794582151789057", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 3, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "15", + "timestampMicros": "1794582151789283", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 3, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "16", + "timestampMicros": "1794582151789284", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "usage": { + "promptTokenCount": "8519", + "cachedContentTokenCount": "2175", + "candidatesTokenCount": "10", + "thoughtsTokenCount": "38", + "totalTokenCount": "8567", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8519" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2175" + } + ] + } + } + ], + "total": { + "promptTokenCount": "8519", + "cachedContentTokenCount": "2175", + "candidatesTokenCount": "10", + "thoughtsTokenCount": "38", + "totalTokenCount": "8567", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8519" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2175" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "17", + "timestampMicros": "1794582151791487", + "trajectoryStateUpdate": { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/python_tool.json b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/python_tool.json new file mode 100644 index 00000000..869a88dc --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/python_tool.json @@ -0,0 +1,652 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "tools": [ + { + "name": "mean", + "description": "Return the sample arithmetic mean of data.\n\n>>> mean([1, 2, 3, 4, 4])\n2.8\n\n>>> from fractions import Fraction as F\n>>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)])\nFraction(13, 21)\n\n>>> from decimal import Decimal as D\n>>> mean([D(\"0.5\"), D(\"0.75\"), D(\"0.625\"), D(\"0.375\")])\nDecimal('0.5625')\n\nIf ``data`` is empty, StatisticsError will be raised.\n\n", + "parametersJsonSchema": "{\"type\": \"object\", \"properties\": {\"data\": {\"type\": \"array\", \"items\": {\"type\": \"number\"}}}, \"required\": [\"data\"]}" + } + ], + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582280450070", + "initializeConversationResponse": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Use the mean tool to calculate the average of 12, 18, and 24." + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582280452942", + "trajectoryStateUpdate": { + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582280486340", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Use the mean tool to calculate the average of 12, 18, and 24.", + "thinkingDelta": "", + "text": "Use the mean tool to calculate the average of 12, 18, and 24." + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582282759903", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "Calling custom tool \"mean\"", + "thinkingDelta": "", + "text": "Calling custom tool \"mean\"", + "customTool": { + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + } + } + } + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582282760323", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Calling custom tool \"mean\"", + "customTool": { + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + } + } + } + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582282760608", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "usage": { + "promptTokenCount": "4414", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "19", + "thoughtsTokenCount": "52", + "totalTokenCount": "4485", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4414" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4414", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "19", + "thoughtsTokenCount": "52", + "totalTokenCount": "4485", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4414" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582282760954", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Calling custom tool \"mean\"", + "customTool": { + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + } + } + } + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582282760999", + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + }, + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187" + } + } + }, + { + "send": { + "toolResponse": { + "id": "call_15472070020580168446", + "responseJson": "{\"result\": 18.0}" + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582282764895", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Calling custom tool \"mean\"", + "customTool": { + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + } + }, + "toolResponse": { + "id": "mean", + "responseJson": "{\"result\": 18.0}" + } + } + } + } + }, + { + "recv": { + "seqNum": "10", + "timestampMicros": "1794582284058883", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "The average", + "thinkingDelta": "", + "text": "The average" + } + } + }, + { + "recv": { + "seqNum": "11", + "timestampMicros": "1794582284134896", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": " of 12, 18, and 24 is **18**.", + "thinkingDelta": "", + "text": "The average of 12, 18, and 24 is **18**." + } + } + }, + { + "recv": { + "seqNum": "12", + "timestampMicros": "1794582284225624", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The average of 12, 18, and 24 is **18**." + } + } + }, + { + "recv": { + "seqNum": "13", + "timestampMicros": "1794582284225763", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The average of 12, 18, and 24 is **18**." + } + } + }, + { + "recv": { + "seqNum": "14", + "timestampMicros": "1794582284225917", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The average of 12, 18, and 24 is **18**." + } + } + }, + { + "recv": { + "seqNum": "15", + "timestampMicros": "1794582284225917", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "usage": { + "promptTokenCount": "8990", + "cachedContentTokenCount": "2382", + "candidatesTokenCount": "39", + "thoughtsTokenCount": "68", + "totalTokenCount": "9097", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8990" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2382" + } + ] + } + } + ], + "total": { + "promptTokenCount": "8990", + "cachedContentTokenCount": "2382", + "candidatesTokenCount": "39", + "thoughtsTokenCount": "68", + "totalTokenCount": "9097", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8990" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2382" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "16", + "timestampMicros": "1794582284227705", + "trajectoryStateUpdate": { + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/structured.json b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/structured.json new file mode 100644 index 00000000..40d551ef --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/structured.json @@ -0,0 +1,354 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "{\"type\": \"object\", \"properties\": {\"word\": {\"type\": \"string\"}}, \"required\": [\"word\"]}", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794584142666042", + "initializeConversationResponse": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Return the word pineapple using the required output schema." + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794584142668855", + "trajectoryStateUpdate": { + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794584142685927", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Return the word pineapple using the required output schema.", + "thinkingDelta": "", + "text": "Return the word pineapple using the required output schema." + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794584145629729", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "Finished", + "thinkingDelta": "", + "text": "Finished", + "finish": { + "outputString": "{\"word\":\"pineapple\"}" + } + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794584145630801", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Finished", + "finish": { + "outputString": "{\"word\":\"pineapple\"}" + } + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794584145630901", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "usage": { + "promptTokenCount": "4289", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "14", + "thoughtsTokenCount": "194", + "totalTokenCount": "4497", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4289" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4289", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "14", + "thoughtsTokenCount": "194", + "totalTokenCount": "4497", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4289" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794584145631141", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Finished", + "finish": { + "outputString": "{\"word\":\"pineapple\"}" + } + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794584145631375", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Finished", + "finish": { + "outputString": "{\"word\":\"pineapple\"}" + } + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794584145633149", + "trajectoryStateUpdate": { + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/tool.json b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/tool.json new file mode 100644 index 00000000..ae78b64b --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/0.1.23/tool.json @@ -0,0 +1,577 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "systemInstructions": { + "appended": { + "appendedSections": [ + { + "title": "user_system_instructions", + "content": "Always use view_file when asked to read a file." + } + ] + } + }, + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "TEST_WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582141616376", + "initializeConversationResponse": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Use view_file to read README.md and tell me the secret word." + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582141618916", + "trajectoryStateUpdate": { + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582141629486", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Use view_file to read README.md and tell me the secret word.", + "thinkingDelta": "", + "text": "Use view_file to read README.md and tell me the secret word." + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582144896299", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "Tool execution", + "thinkingDelta": "", + "text": "Tool execution", + "viewFile": { + "filePath": "file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md", + "startLine": 0, + "endLine": 799 + } + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582144896952", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Tool execution", + "viewFile": { + "filePath": "file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md", + "startLine": 0, + "endLine": 799 + } + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582144897240", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "usage": { + "promptTokenCount": "4290", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "80", + "thoughtsTokenCount": "117", + "totalTokenCount": "4487", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4290" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4290", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "80", + "thoughtsTokenCount": "117", + "totalTokenCount": "4487", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4290" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582144897647", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Tool execution", + "viewFile": { + "filePath": "file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md", + "startLine": 0, + "endLine": 799 + } + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582144898013", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Tool execution", + "viewFile": { + "filePath": "file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md", + "startLine": 0, + "endLine": 0 + } + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582146951988", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "The secret", + "thinkingDelta": "", + "text": "The secret" + } + } + }, + { + "recv": { + "seqNum": "10", + "timestampMicros": "1794582147083940", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": " word in [README.md](file:///private/var/folders/1r/0r49yqc", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc" + } + } + }, + { + "recv": { + "seqNum": "11", + "timestampMicros": "1794582147238860", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "973s87vl4n1x_3j1m0000gn/T/pytest-of", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of" + } + } + }, + { + "recv": { + "seqNum": "12", + "timestampMicros": "1794582147389136", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L" + } + } + }, + { + "recv": { + "seqNum": "13", + "timestampMicros": "1794582147514771", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "1) is **pineapple**.", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L1) is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "14", + "timestampMicros": "1794582147515270", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L1) is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "15", + "timestampMicros": "1794582147515361", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L1) is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "16", + "timestampMicros": "1794582147518890", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L1) is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "17", + "timestampMicros": "1794582147518890", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "usage": { + "promptTokenCount": "9019", + "cachedContentTokenCount": "2259", + "candidatesTokenCount": "163", + "thoughtsTokenCount": "138", + "totalTokenCount": "9320", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "9019" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2259" + } + ] + } + } + ], + "total": { + "promptTokenCount": "9019", + "cachedContentTokenCount": "2259", + "candidatesTokenCount": "163", + "thoughtsTokenCount": "138", + "totalTokenCount": "9320", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "9019" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2259" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "18", + "timestampMicros": "1794582147520670", + "trajectoryStateUpdate": { + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/latest/cancel.json b/py/src/braintrust/integrations/antigravity/cassettes/latest/cancel.json new file mode 100644 index 00000000..b082e433 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/latest/cancel.json @@ -0,0 +1,226 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582147645091", + "initializeConversationResponse": { + "cascadeId": "edaa2b7a92ac93ec7d863246b93571dd", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Reply with exactly: antigravity tracing complete" + } + ] + } + } + }, + { + "send": { + "haltRequest": true + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582147646508", + "trajectoryStateUpdate": { + "trajectoryId": "edaa2b7a92ac93ec7d863246b93571dd", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582147657527", + "stepUpdate": { + "cascadeId": "edaa2b7a92ac93ec7d863246b93571dd", + "trajectoryId": "edaa2b7a92ac93ec7d863246b93571dd", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Reply with exactly: antigravity tracing complete", + "thinkingDelta": "", + "text": "Reply with exactly: antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582147661036", + "trajectoryStateUpdate": { + "trajectoryId": "edaa2b7a92ac93ec7d863246b93571dd", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/latest/chat.json b/py/src/braintrust/integrations/antigravity/cassettes/latest/chat.json new file mode 100644 index 00000000..ae747863 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/latest/chat.json @@ -0,0 +1,332 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582005876262", + "initializeConversationResponse": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Reply with exactly: antigravity tracing complete" + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582005879508", + "trajectoryStateUpdate": { + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582005889778", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Reply with exactly: antigravity tracing complete", + "thinkingDelta": "", + "text": "Reply with exactly: antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582008018830", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "antigravity tracing complete", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582008024828", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582008024961", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582008026147", + "stepUpdate": { + "cascadeId": "4c2b1a384f84d2ad4703d59f9885b554", + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582008026147", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "usage": { + "promptTokenCount": "4213", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "5", + "thoughtsTokenCount": "56", + "totalTokenCount": "4274", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4213" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4213", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "5", + "thoughtsTokenCount": "56", + "totalTokenCount": "4274", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4213" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582008028043", + "trajectoryStateUpdate": { + "trajectoryId": "4c2b1a384f84d2ad4703d59f9885b554", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/latest/document.json b/py/src/braintrust/integrations/antigravity/cassettes/latest/document.json new file mode 100644 index 00000000..95f6ad20 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/latest/document.json @@ -0,0 +1,412 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582465566755", + "initializeConversationResponse": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "What is the secret word in this document?" + }, + { + "media": { + "mimeType": "text/plain", + "data": "VGhlIHNlY3JldCB3b3JkIGlzIHBpbmVhcHBsZS4=" + } + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582465572784", + "trajectoryStateUpdate": { + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582465590444", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "What is the secret word in this document?", + "thinkingDelta": "", + "text": "What is the secret word in this document?" + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582470555245", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 1, + "state": "STATE_ERROR", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "errorMessage": "Denied by policy \"confirm_run_command\".", + "thinking": "", + "textDelta": "Denied by policy \"confirm_run_command\". (\"denied by pre-tool hook: Denied by policy \\\"confirm_run_command\\\".\")", + "thinkingDelta": "", + "text": "Denied by policy \"confirm_run_command\". (\"denied by pre-tool hook: Denied by policy \\\"confirm_run_command\\\".\")", + "error": { + "errorMessage": "Denied by policy \"confirm_run_command\". (\"denied by pre-tool hook: Denied by policy \\\"confirm_run_command\\\".\")", + "httpCode": 0 + } + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582470556031", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "usage": { + "promptTokenCount": "4218", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "134", + "thoughtsTokenCount": "288", + "totalTokenCount": "4640", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4218" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4218", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "134", + "thoughtsTokenCount": "288", + "totalTokenCount": "4640", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4218" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582474689291", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "The secret word is **pineapple**.", + "thinkingDelta": "", + "text": "The secret word is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582474704013", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582474704146", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582474706247", + "stepUpdate": { + "cascadeId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "stepIndex": 2, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "10", + "timestampMicros": "1794582474706247", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "usage": { + "promptTokenCount": "8927", + "cachedContentTokenCount": "2188", + "candidatesTokenCount": "141", + "thoughtsTokenCount": "602", + "totalTokenCount": "9670", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8927" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2188" + } + ] + } + } + ], + "total": { + "promptTokenCount": "8927", + "cachedContentTokenCount": "2188", + "candidatesTokenCount": "141", + "thoughtsTokenCount": "602", + "totalTokenCount": "9670", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8927" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2188" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "11", + "timestampMicros": "1794582474708301", + "trajectoryStateUpdate": { + "trajectoryId": "53a3ed29f9b6a3d8a33000b8e8c2dc0d", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/latest/multiple_turns.json b/py/src/braintrust/integrations/antigravity/cassettes/latest/multiple_turns.json new file mode 100644 index 00000000..0500e0f5 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/latest/multiple_turns.json @@ -0,0 +1,504 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582147784720", + "initializeConversationResponse": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Reply with exactly: antigravity tracing complete" + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582147786113", + "trajectoryStateUpdate": { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582147795578", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Reply with exactly: antigravity tracing complete", + "thinkingDelta": "", + "text": "Reply with exactly: antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582149691338", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "antigravity tracing complete", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582149702673", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582149702845", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582149705522", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582149705522", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "usage": { + "promptTokenCount": "4209", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "5", + "thoughtsTokenCount": "22", + "totalTokenCount": "4236", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4209" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4209", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "5", + "thoughtsTokenCount": "22", + "totalTokenCount": "4236", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4209" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582149708045", + "trajectoryStateUpdate": { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "state": "STATE_FULLY_IDLE" + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Reply with exactly: antigravity tracing complete" + } + ] + } + } + }, + { + "recv": { + "seqNum": "10", + "timestampMicros": "1794582149709032", + "trajectoryStateUpdate": { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "11", + "timestampMicros": "1794582149711998", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 2, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Reply with exactly: antigravity tracing complete", + "thinkingDelta": "", + "text": "Reply with exactly: antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "12", + "timestampMicros": "1794582151788602", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 3, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "antigravity tracing complete", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "13", + "timestampMicros": "1794582151788892", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 3, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "14", + "timestampMicros": "1794582151789057", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 3, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "15", + "timestampMicros": "1794582151789283", + "stepUpdate": { + "cascadeId": "41ab9bc3ab6652e13fde72c222f7b058", + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "stepIndex": 3, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "antigravity tracing complete" + } + } + }, + { + "recv": { + "seqNum": "16", + "timestampMicros": "1794582151789284", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "usage": { + "promptTokenCount": "8519", + "cachedContentTokenCount": "2175", + "candidatesTokenCount": "10", + "thoughtsTokenCount": "38", + "totalTokenCount": "8567", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8519" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2175" + } + ] + } + } + ], + "total": { + "promptTokenCount": "8519", + "cachedContentTokenCount": "2175", + "candidatesTokenCount": "10", + "thoughtsTokenCount": "38", + "totalTokenCount": "8567", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8519" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2175" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "17", + "timestampMicros": "1794582151791487", + "trajectoryStateUpdate": { + "trajectoryId": "41ab9bc3ab6652e13fde72c222f7b058", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/latest/python_tool.json b/py/src/braintrust/integrations/antigravity/cassettes/latest/python_tool.json new file mode 100644 index 00000000..869a88dc --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/latest/python_tool.json @@ -0,0 +1,652 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "tools": [ + { + "name": "mean", + "description": "Return the sample arithmetic mean of data.\n\n>>> mean([1, 2, 3, 4, 4])\n2.8\n\n>>> from fractions import Fraction as F\n>>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)])\nFraction(13, 21)\n\n>>> from decimal import Decimal as D\n>>> mean([D(\"0.5\"), D(\"0.75\"), D(\"0.625\"), D(\"0.375\")])\nDecimal('0.5625')\n\nIf ``data`` is empty, StatisticsError will be raised.\n\n", + "parametersJsonSchema": "{\"type\": \"object\", \"properties\": {\"data\": {\"type\": \"array\", \"items\": {\"type\": \"number\"}}}, \"required\": [\"data\"]}" + } + ], + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582280450070", + "initializeConversationResponse": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Use the mean tool to calculate the average of 12, 18, and 24." + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582280452942", + "trajectoryStateUpdate": { + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582280486340", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Use the mean tool to calculate the average of 12, 18, and 24.", + "thinkingDelta": "", + "text": "Use the mean tool to calculate the average of 12, 18, and 24." + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582282759903", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "Calling custom tool \"mean\"", + "thinkingDelta": "", + "text": "Calling custom tool \"mean\"", + "customTool": { + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + } + } + } + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582282760323", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Calling custom tool \"mean\"", + "customTool": { + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + } + } + } + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582282760608", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "usage": { + "promptTokenCount": "4414", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "19", + "thoughtsTokenCount": "52", + "totalTokenCount": "4485", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4414" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4414", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "19", + "thoughtsTokenCount": "52", + "totalTokenCount": "4485", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4414" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582282760954", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Calling custom tool \"mean\"", + "customTool": { + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + } + } + } + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582282760999", + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + }, + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187" + } + } + }, + { + "send": { + "toolResponse": { + "id": "call_15472070020580168446", + "responseJson": "{\"result\": 18.0}" + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582282764895", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Calling custom tool \"mean\"", + "customTool": { + "toolCall": { + "id": "call_15472070020580168446", + "name": "mean", + "argumentsJson": "{\"data\":[12,18,24]}", + "arguments": { + "fields": [ + { + "name": "data", + "value": { + "listValue": { + "values": [ + { + "numberValue": 12 + }, + { + "numberValue": 18 + }, + { + "numberValue": 24 + } + ] + } + } + } + ] + } + }, + "toolResponse": { + "id": "mean", + "responseJson": "{\"result\": 18.0}" + } + } + } + } + }, + { + "recv": { + "seqNum": "10", + "timestampMicros": "1794582284058883", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "The average", + "thinkingDelta": "", + "text": "The average" + } + } + }, + { + "recv": { + "seqNum": "11", + "timestampMicros": "1794582284134896", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": " of 12, 18, and 24 is **18**.", + "thinkingDelta": "", + "text": "The average of 12, 18, and 24 is **18**." + } + } + }, + { + "recv": { + "seqNum": "12", + "timestampMicros": "1794582284225624", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The average of 12, 18, and 24 is **18**." + } + } + }, + { + "recv": { + "seqNum": "13", + "timestampMicros": "1794582284225763", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The average of 12, 18, and 24 is **18**." + } + } + }, + { + "recv": { + "seqNum": "14", + "timestampMicros": "1794582284225917", + "stepUpdate": { + "cascadeId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "stepIndex": 2, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The average of 12, 18, and 24 is **18**." + } + } + }, + { + "recv": { + "seqNum": "15", + "timestampMicros": "1794582284225917", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "usage": { + "promptTokenCount": "8990", + "cachedContentTokenCount": "2382", + "candidatesTokenCount": "39", + "thoughtsTokenCount": "68", + "totalTokenCount": "9097", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8990" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2382" + } + ] + } + } + ], + "total": { + "promptTokenCount": "8990", + "cachedContentTokenCount": "2382", + "candidatesTokenCount": "39", + "thoughtsTokenCount": "68", + "totalTokenCount": "9097", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "8990" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2382" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "16", + "timestampMicros": "1794582284227705", + "trajectoryStateUpdate": { + "trajectoryId": "1cc1f3b03b98aa78f0b2e45bbc5b8187", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/latest/structured.json b/py/src/braintrust/integrations/antigravity/cassettes/latest/structured.json new file mode 100644 index 00000000..40d551ef --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/latest/structured.json @@ -0,0 +1,354 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "WORKSPACE" + } + } + ], + "finishToolSchemaJson": "{\"type\": \"object\", \"properties\": {\"word\": {\"type\": \"string\"}}, \"required\": [\"word\"]}", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794584142666042", + "initializeConversationResponse": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Return the word pineapple using the required output schema." + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794584142668855", + "trajectoryStateUpdate": { + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794584142685927", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Return the word pineapple using the required output schema.", + "thinkingDelta": "", + "text": "Return the word pineapple using the required output schema." + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794584145629729", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "Finished", + "thinkingDelta": "", + "text": "Finished", + "finish": { + "outputString": "{\"word\":\"pineapple\"}" + } + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794584145630801", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Finished", + "finish": { + "outputString": "{\"word\":\"pineapple\"}" + } + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794584145630901", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "usage": { + "promptTokenCount": "4289", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "14", + "thoughtsTokenCount": "194", + "totalTokenCount": "4497", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4289" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4289", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "14", + "thoughtsTokenCount": "194", + "totalTokenCount": "4497", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4289" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794584145631141", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Finished", + "finish": { + "outputString": "{\"word\":\"pineapple\"}" + } + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794584145631375", + "stepUpdate": { + "cascadeId": "e2a0a7488908ad2c428cfcff1d688727", + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Finished", + "finish": { + "outputString": "{\"word\":\"pineapple\"}" + } + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794584145633149", + "trajectoryStateUpdate": { + "trajectoryId": "e2a0a7488908ad2c428cfcff1d688727", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/cassettes/latest/tool.json b/py/src/braintrust/integrations/antigravity/cassettes/latest/tool.json new file mode 100644 index 00000000..ae78b64b --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/cassettes/latest/tool.json @@ -0,0 +1,577 @@ +[ + { + "send": { + "config": { + "cascadeId": "", + "systemInstructions": { + "appended": { + "appendedSections": [ + { + "title": "user_system_instructions", + "content": "Always use view_file when asked to read a file." + } + ] + } + }, + "harnessSideTools": { + "find": { + "enabled": false + }, + "runCommand": { + "enabled": true, + "maxTimeoutMs": 0, + "enableDaemonCommands": false, + "enableSandbox": false + }, + "subagents": { + "enabled": false + }, + "userQuestions": { + "enabled": false + }, + "fileEdit": { + "enabled": true + }, + "viewFile": { + "enabled": true + }, + "writeToFile": { + "enabled": true + }, + "grepSearch": { + "enabled": false + }, + "listDir": { + "enabled": false + }, + "generateImage": { + "enabled": false + }, + "searchWeb": { + "enabled": false + }, + "readUrlContent": { + "enabled": false + }, + "manageTask": { + "enabled": true + }, + "schedule": { + "enabled": false + }, + "runWorkflow": { + "enabled": false + } + }, + "compactionThreshold": 65536, + "workspaces": [ + { + "filesystemWorkspace": { + "directory": "TEST_WORKSPACE" + } + } + ], + "finishToolSchemaJson": "", + "appDataDir": "TEST_WORKSPACE", + "models": [ + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.1-flash-lite-image", + "types": [ + "MODEL_TYPE_IMAGE" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + }, + { + "name": "gemini-3.8-flash", + "types": [ + "MODEL_TYPE_TEXT" + ], + "geminiApiEndpoint": { + "baseUrl": "", + "apiKey": "REDACTED" + } + } + ], + "sessionContinuationMode": "SESSION_CONTINUATION_MODE_UNSPECIFIED", + "policyConfig": { + "rules": [ + { + "tool": "run_command", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_DENY", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + }, + { + "tool": "*", + "serverName": "", + "name": "confirm_run_command", + "decision": "POLICY_DECISION_ALLOW", + "denyReason": "", + "isDynamic": false, + "ruleId": "" + } + ], + "workspaceContainment": "WORKSPACE_CONTAINMENT_UNSPECIFIED" + }, + "agentBehavior": "AGENT_BEHAVIOR_MINIMAL", + "compactionConfig": { + "tokenThreshold": 65536 + } + } + } + }, + { + "recv": { + "seqNum": "1", + "timestampMicros": "1794582141616376", + "initializeConversationResponse": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "sandboxStatus": { + "available": true, + "unavailableReason": "" + } + } + } + }, + { + "send": { + "userInput": { + "parts": [ + { + "text": "Use view_file to read README.md and tell me the secret word." + } + ] + } + } + }, + { + "recv": { + "seqNum": "2", + "timestampMicros": "1794582141618916", + "trajectoryStateUpdate": { + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "state": "STATE_RUNNING" + } + } + }, + { + "recv": { + "seqNum": "3", + "timestampMicros": "1794582141629486", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 0, + "state": "STATE_DONE", + "source": "SOURCE_USER", + "target": "TARGET_MODEL", + "thinking": "", + "textDelta": "Use view_file to read README.md and tell me the secret word.", + "thinkingDelta": "", + "text": "Use view_file to read README.md and tell me the secret word." + } + } + }, + { + "recv": { + "seqNum": "4", + "timestampMicros": "1794582144896299", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "Tool execution", + "thinkingDelta": "", + "text": "Tool execution", + "viewFile": { + "filePath": "file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md", + "startLine": 0, + "endLine": 799 + } + } + } + }, + { + "recv": { + "seqNum": "5", + "timestampMicros": "1794582144896952", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Tool execution", + "viewFile": { + "filePath": "file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md", + "startLine": 0, + "endLine": 799 + } + } + } + }, + { + "recv": { + "seqNum": "6", + "timestampMicros": "1794582144897240", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "usage": { + "promptTokenCount": "4290", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "80", + "thoughtsTokenCount": "117", + "totalTokenCount": "4487", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4290" + } + ] + } + } + ], + "total": { + "promptTokenCount": "4290", + "cachedContentTokenCount": "0", + "candidatesTokenCount": "80", + "thoughtsTokenCount": "117", + "totalTokenCount": "4487", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "4290" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "7", + "timestampMicros": "1794582144897647", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 1, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Tool execution", + "viewFile": { + "filePath": "file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md", + "startLine": 0, + "endLine": 799 + } + } + } + }, + { + "recv": { + "seqNum": "8", + "timestampMicros": "1794582144898013", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 1, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_ENVIRONMENT", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "Tool execution", + "viewFile": { + "filePath": "file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md", + "startLine": 0, + "endLine": 0 + } + } + } + }, + { + "recv": { + "seqNum": "9", + "timestampMicros": "1794582146951988", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "The secret", + "thinkingDelta": "", + "text": "The secret" + } + } + }, + { + "recv": { + "seqNum": "10", + "timestampMicros": "1794582147083940", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": " word in [README.md](file:///private/var/folders/1r/0r49yqc", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc" + } + } + }, + { + "recv": { + "seqNum": "11", + "timestampMicros": "1794582147238860", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "973s87vl4n1x_3j1m0000gn/T/pytest-of", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of" + } + } + }, + { + "recv": { + "seqNum": "12", + "timestampMicros": "1794582147389136", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L" + } + } + }, + { + "recv": { + "seqNum": "13", + "timestampMicros": "1794582147514771", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "1) is **pineapple**.", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L1) is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "14", + "timestampMicros": "1794582147515270", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L1) is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "15", + "timestampMicros": "1794582147515361", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_ACTIVE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L1) is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "16", + "timestampMicros": "1794582147518890", + "stepUpdate": { + "cascadeId": "7e5c78d3c4c87d18bee1cca797a737a3", + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "stepIndex": 2, + "state": "STATE_DONE", + "source": "SOURCE_MODEL", + "target": "TARGET_USER", + "thinking": "", + "textDelta": "", + "thinkingDelta": "", + "text": "The secret word in [README.md](file:///private/var/folders/1r/0r49yqc973s87vl4n1x_3j1m0000gn/T/pytest-of-abhijeetprasad/pytest-67/test_builtin_tool0/README.md#L1) is **pineapple**." + } + } + }, + { + "recv": { + "seqNum": "17", + "timestampMicros": "1794582147518890", + "usageUpdate": { + "agents": [ + { + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "usage": { + "promptTokenCount": "9019", + "cachedContentTokenCount": "2259", + "candidatesTokenCount": "163", + "thoughtsTokenCount": "138", + "totalTokenCount": "9320", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "9019" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2259" + } + ] + } + } + ], + "total": { + "promptTokenCount": "9019", + "cachedContentTokenCount": "2259", + "candidatesTokenCount": "163", + "thoughtsTokenCount": "138", + "totalTokenCount": "9320", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "9019" + } + ], + "cacheTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": "2259" + } + ] + } + } + } + }, + { + "recv": { + "seqNum": "18", + "timestampMicros": "1794582147520670", + "trajectoryStateUpdate": { + "trajectoryId": "7e5c78d3c4c87d18bee1cca797a737a3", + "state": "STATE_FULLY_IDLE" + } + } + } +] diff --git a/py/src/braintrust/integrations/antigravity/integration.py b/py/src/braintrust/integrations/antigravity/integration.py new file mode 100644 index 00000000..15ec47e4 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/integration.py @@ -0,0 +1,15 @@ +"""Antigravity integration orchestration.""" + +from braintrust.integrations.base import BaseIntegration + +from .patchers import AgentPatcher, ChatPatcher, ConversationLifecyclePatcher, ReceiveStepsPatcher, ToolExecutePatcher + + +class AntigravityIntegration(BaseIntegration): + """Trace Google Antigravity's direct, streaming chat API.""" + + name = "antigravity" + import_names = ("google.antigravity",) + distribution_names = ("google-antigravity",) + min_version = "0.1.23" + patchers = (AgentPatcher, ChatPatcher, ReceiveStepsPatcher, ToolExecutePatcher, ConversationLifecyclePatcher) diff --git a/py/src/braintrust/integrations/antigravity/patchers.py b/py/src/braintrust/integrations/antigravity/patchers.py new file mode 100644 index 00000000..4de6fa71 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/patchers.py @@ -0,0 +1,79 @@ +"""Patch the shared Conversation entry points used by Agent.chat().""" + +from braintrust.integrations.base import CompositeFunctionWrapperPatcher, FunctionWrapperPatcher + +from .tracing import ( + _agent_chat_wrapper, + _agent_exit_wrapper, + _chat_wrapper, + _lifecycle_wrapper, + _receive_steps_wrapper, + _tool_execute_wrapper, +) + + +class _AgentChatPatcher(FunctionWrapperPatcher): + name = "antigravity.agent.chat" + target_path = "Agent.chat" + wrapper = _agent_chat_wrapper + + +class _AgentExitPatcher(FunctionWrapperPatcher): + name = "antigravity.agent.exit" + target_path = "Agent.__aexit__" + wrapper = _agent_exit_wrapper + + +class AgentPatcher(CompositeFunctionWrapperPatcher): + name = "antigravity.agent" + sub_patchers = (_AgentChatPatcher, _AgentExitPatcher) + + @classmethod + def wrap_target(cls, target): + for patcher in cls.sub_patchers: + method = getattr(target, patcher.target_path.rsplit(".", 1)[-1], None) + # setup() marks methods; manual wrapping otherwise marks the class. + # Honor either entry point's marker before adding another wrapper. + if not patcher.has_patch_marker(method): + patcher.wrap_target(target) + return target + + +class ChatPatcher(FunctionWrapperPatcher): + name = "antigravity.conversation.chat" + target_module = "google.antigravity.conversation.conversation" + target_path = "Conversation.chat" + wrapper = _chat_wrapper + + +class ReceiveStepsPatcher(FunctionWrapperPatcher): + name = "antigravity.conversation.receive_steps" + target_module = "google.antigravity.conversation.conversation" + target_path = "Conversation.receive_steps" + wrapper = _receive_steps_wrapper + + +class ToolExecutePatcher(FunctionWrapperPatcher): + name = "antigravity.tool.execute" + target_module = "google.antigravity.tools.tool_runner" + target_path = "ToolRunner.execute" + wrapper = _tool_execute_wrapper + + +class _CancelPatcher(FunctionWrapperPatcher): + name = "antigravity.conversation.cancel" + target_module = "google.antigravity.conversation.conversation" + target_path = "Conversation.cancel" + wrapper = _lifecycle_wrapper + + +class _DisconnectPatcher(FunctionWrapperPatcher): + name = "antigravity.conversation.disconnect" + target_module = "google.antigravity.conversation.conversation" + target_path = "Conversation.disconnect" + wrapper = _lifecycle_wrapper + + +class ConversationLifecyclePatcher(CompositeFunctionWrapperPatcher): + name = "antigravity.conversation.lifecycle" + sub_patchers = (_CancelPatcher, _DisconnectPatcher) diff --git a/py/src/braintrust/integrations/antigravity/test_antigravity.py b/py/src/braintrust/integrations/antigravity/test_antigravity.py new file mode 100644 index 00000000..f5c2eb12 --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/test_antigravity.py @@ -0,0 +1,324 @@ +"""Real Antigravity agent coverage with recorded harness transport.""" + +import asyncio +import gc +import statistics + +import pytest +from braintrust import logger +from braintrust.integrations.antigravity import AntigravityIntegration, setup_antigravity, wrap_antigravity_agent +from braintrust.integrations.antigravity._test_transport import cassette_transport +from braintrust.integrations.test_utils import verify_autoinstrument_script +from braintrust.logger import Attachment, current_span, start_span +from braintrust.test_helpers import init_test_logger +from google.antigravity import Agent, LocalAgentConfig, types +from google.antigravity.tools.tool_runner import ToolWithSchema + + +PROMPT = "Reply with exactly: antigravity tracing complete" + + +@pytest.fixture +def memory_logger(): + init_test_logger("test-antigravity") + with logger._internal_with_memory_background_logger() as bgl: + yield bgl + + +def agent_config(tmp_path): + return LocalAgentConfig(model="gemini-3.8-flash", app_data_dir=str(tmp_path)).lightweight() + + +def test_setup_and_wrap_are_idempotent(): + assert AntigravityIntegration.setup() + chat = Agent.__dict__["chat"] + exit_method = Agent.__dict__["__aexit__"] + for _ in range(2): + assert wrap_antigravity_agent(Agent) is Agent + assert AntigravityIntegration.setup() + assert Agent.__dict__["chat"] is chat + assert Agent.__dict__["__aexit__"] is exit_method + + +@pytest.mark.asyncio +@pytest.mark.parametrize("accessor", ["text", "stream", "chunks", "concurrent", "manual"]) +async def test_chat(memory_logger, tmp_path, accessor): + if accessor == "manual": + assert wrap_antigravity_agent(Agent) is Agent + else: + assert setup_antigravity(project="test-antigravity") + assert AntigravityIntegration.setup() + with cassette_transport("chat"): + async with Agent(agent_config(tmp_path)) as agent: + with start_span(name="parent") as parent: + response = await agent.chat(PROMPT) + assert isinstance(response, types.ChatResponse) + assert current_span() is parent + if accessor == "stream": + text = "".join([token async for token in response]) + elif accessor == "chunks": + await response.resolve() + text = await response.text() + elif accessor == "concurrent": + text, again = await asyncio.gather(response.text(), response.text()) + assert text == again + else: + text = await response.text() + assert "antigravity tracing complete" in text.lower() + assert await response.text() == text + assert current_span() is parent + assert response.usage_metadata.total_token_count > 0 + spans = memory_logger.pop() + chats = [s for s in spans if s.get("span_attributes", {}).get("name") == "antigravity.chat"] + assert len(chats) == 1 + chat = chats[0] + assert chat["span_attributes"]["type"] == "task" + assert chat["span_parents"] == [parent.span_id] + assert chat["input"][0]["content"][0]["text"] == PROMPT + assert chat["output"][0]["content"] == text + assert chat["metadata"]["model"] == "gemini-3.8-flash" + assert chat["metadata"]["tools"] + assert chat["metrics"]["tokens"] == response.usage_metadata.total_token_count + assert chat["metrics"]["completion_tokens"] == (response.usage_metadata.candidates_token_count or 0) + ( + response.usage_metadata.thoughts_token_count or 0 + ) + assert chat["metrics"]["time_to_first_token"] >= 0 + assert chat["metrics"]["end"] >= chat["metrics"]["start"] + children = [s for s in spans if s["span_parents"] == [chat["span_id"]]] + assert children + for span in [chat, *children]: + assert span["context"]["span_origin"]["instrumentation"]["name"] == "antigravity-auto" + + +@pytest.mark.asyncio +@pytest.mark.parametrize("exit_path", ["drop", "partial", "close", "disconnect"]) +async def test_stream_cleanup(memory_logger, tmp_path, exit_path): + assert AntigravityIntegration.setup() + with cassette_transport("chat"): + async with Agent(agent_config(tmp_path)) as agent: + response = await agent.chat(PROMPT) + before = current_span() + if exit_path == "partial": + async for _ in response: + break + elif exit_path == "close": + await response._chunk_stream.aclose() + if exit_path != "disconnect": + del response + # The SDK's text cursor and nested chunk cursor are async + # generators; let Python finish their queued finalizers. + for _ in range(5): + gc.collect() + await asyncio.sleep(0) + spans = memory_logger.pop() + assert any(s["span_attributes"]["name"] == "antigravity.chat" and "end" in s["metrics"] for s in spans) + assert current_span() is before + gc.collect() + remaining = memory_logger.pop() + if exit_path != "disconnect": + assert remaining == [] + else: + spans = remaining + chats = [s for s in spans if s.get("span_attributes", {}).get("name") == "antigravity.chat"] + assert len(chats) == 1 + assert "end" in chats[0]["metrics"] + + +@pytest.mark.asyncio +async def test_send_receive_is_not_instrumented(memory_logger, tmp_path): + assert AntigravityIntegration.setup() + with cassette_transport("chat"): + async with Agent(agent_config(tmp_path)) as agent: + await agent.conversation.send(PROMPT) + async for _ in agent.conversation.receive_steps(): + pass + assert memory_logger.pop() == [] + + +@pytest.mark.parametrize("import_order", ["before", "after"]) +def test_auto_instrument(monkeypatch, import_order): + monkeypatch.setenv("BRAINTRUST_ANTIGRAVITY_IMPORT_ORDER", import_order) + verify_autoinstrument_script("test_auto_antigravity.py", timeout=120) + + +@pytest.mark.asyncio +async def test_builtin_tool(memory_logger, tmp_path): + assert AntigravityIntegration.setup() + (tmp_path / "README.md").write_text("The secret word is pineapple.", encoding="utf-8") + config = agent_config(tmp_path) + config.workspaces = [str(tmp_path)] + config.system_instructions = "Always use view_file when asked to read a file." + with cassette_transport("tool"): + async with Agent(config) as agent: + response = await agent.chat("Use view_file to read README.md and tell me the secret word.") + assert "pineapple" in (await response.text()).lower() + spans = memory_logger.pop() + chat = next(s for s in spans if s["span_attributes"]["name"] == "antigravity.chat") + assert chat["input"][0] == {"role": "system", "content": config.system_instructions} + tools = [s for s in spans if s["span_attributes"]["type"] == "tool"] + view_file = next(s for s in tools if s["span_attributes"]["name"] == "view_file") + assert view_file["span_parents"] == [chat["span_id"]] + assert view_file["input"] + assert "end" in view_file["metrics"] + + +@pytest.mark.asyncio +async def test_cancel_active_turn(memory_logger, tmp_path): + assert AntigravityIntegration.setup() + with cassette_transport("cancel"): + async with Agent(agent_config(tmp_path)) as agent: + response = await agent.chat(PROMPT) + await response.cancel() + with pytest.raises(types.AntigravityCancelledError) as raised: + await response.text() + spans = memory_logger.pop() + chat = next(s for s in spans if s["span_attributes"]["name"] == "antigravity.chat") + assert "end" in chat["metrics"] + assert str(raised.value) in chat["error"] + + +@pytest.mark.asyncio +async def test_multiple_turns(memory_logger, tmp_path): + assert AntigravityIntegration.setup() + counts = [] + responses = [] + with cassette_transport("multiple_turns"): + async with Agent(agent_config(tmp_path)) as agent: + for _ in range(2): + response = await agent.chat(PROMPT) + await response.text() + responses.append(response) + counts.append(response.usage_metadata.total_token_count) + assert await responses[0].text() == await responses[-1].text() + total = agent.conversation.total_usage.total_token_count + chats = [s for s in memory_logger.pop() if s["span_attributes"]["name"] == "antigravity.chat"] + assert len(chats) == 2 + assert [s["metrics"]["tokens"] for s in chats] == counts + assert sum(counts) == total + + +@pytest.mark.asyncio +async def test_python_tool(memory_logger, tmp_path): + assert AntigravityIntegration.setup() + # A standard-library callable, executed by the real ToolRunner. + mean = ToolWithSchema( + statistics.mean, + { + "type": "object", + "properties": {"data": {"type": "array", "items": {"type": "number"}}}, + "required": ["data"], + }, + ) + config = agent_config(tmp_path) + config.tools = [mean] + with cassette_transport("python_tool"): + async with Agent(config) as agent: + response = await agent.chat("Use the mean tool to calculate the average of 12, 18, and 24.") + assert "18" in await response.text() + spans = memory_logger.pop() + chat = next(s for s in spans if s["span_attributes"]["name"] == "antigravity.chat") + tools = [s for s in spans if s["span_attributes"]["name"] == "mean"] + assert len(tools) == 1 + assert tools[0]["span_attributes"]["type"] == "tool" + assert tools[0]["span_parents"] == [chat["span_id"]] + assert tools[0]["input"] == {"data": [12, 18, 24]} + assert tools[0]["output"] == 18 + definitions = chat["metadata"]["tools"] + assert any(t.get("function", {}).get("name") == "mean" for t in definitions) + assert tools[0]["context"]["span_origin"]["instrumentation"]["name"] == "antigravity-auto" + + +@pytest.mark.asyncio +async def test_provider_error(memory_logger, tmp_path): + assert AntigravityIntegration.setup() + with cassette_transport("chat"): + async with Agent(agent_config(tmp_path)) as agent: + response = await agent.chat(PROMPT) + # Inject a transport failure into the real SDK queue. Successful + # recordings cannot provoke an unexpected connection loss. + error = types.AntigravityConnectionError("Connection lost") + await agent.conversation.connection._processor.step_queue.put(error) + for _ in range(2): + with pytest.raises(types.AntigravityConnectionError) as raised: + await response.text() + assert raised.value is error + chat = next(s for s in memory_logger.pop() if s["span_attributes"]["name"] == "antigravity.chat") + assert "Connection lost" in chat["error"] + assert "end" in chat["metrics"] + + +@pytest.mark.asyncio +async def test_failed_send_does_not_reuse_previous_usage(memory_logger, tmp_path, monkeypatch): + assert AntigravityIntegration.setup() + with cassette_transport("chat"): + async with Agent(agent_config(tmp_path)) as agent: + response = await agent.chat(PROMPT) + await response.text() + error = types.AntigravityConnectionError("Send failed") + + async def fail_send(*args, **kwargs): + raise error + + # Failure before Conversation.send establishes a new turn must + # not attribute the previous successful turn's tokens to this one. + monkeypatch.setattr(agent.conversation, "send", fail_send) + with pytest.raises(types.AntigravityConnectionError) as raised: + await agent.chat(PROMPT) + assert raised.value is error + chats = [s for s in memory_logger.pop() if s["span_attributes"]["name"] == "antigravity.chat"] + assert len(chats) == 2 + failed = next(s for s in chats if "error" in s) + assert "tokens" not in failed["metrics"] + assert "prompt_tokens" not in failed["metrics"] + assert "completion_tokens" not in failed["metrics"] + + +@pytest.mark.asyncio +async def test_metadata_failure_does_not_leave_pending_span(memory_logger, tmp_path, monkeypatch): + assert AntigravityIntegration.setup() + with cassette_transport("chat"): + async with Agent(agent_config(tmp_path)) as agent: + runner = agent.conversation.connection._tool_runner + + def fail_tool_names(self): + raise RuntimeError("Cannot inspect tools") + + # A telemetry-only inspection failure must preserve the real + # response without leaving a partially initialized chat span. + monkeypatch.setattr(type(runner), "tool_names", property(fail_tool_names)) + response = await agent.chat(PROMPT) + assert "antigravity tracing complete" in (await response.text()).lower() + assert memory_logger.pop() == [] + + +@pytest.mark.asyncio +async def test_document_input(memory_logger, tmp_path): + assert AntigravityIntegration.setup() + document = types.Document(data=b"The secret word is pineapple.", mime_type="text/plain") + with cassette_transport("document"): + async with Agent(agent_config(tmp_path)) as agent: + response = await agent.chat(["What is the secret word in this document?", document]) + assert "pineapple" in (await response.text()).lower() + chat = next(s for s in memory_logger.pop() if s["span_attributes"]["name"] == "antigravity.chat") + attachment = chat["input"][0]["content"][1]["file"]["file_data"] + assert isinstance(attachment, Attachment) + assert attachment.reference["content_type"] == "text/plain" + assert document.data == b"The secret word is pineapple." + + +@pytest.mark.asyncio +async def test_structured_output(memory_logger, tmp_path): + assert AntigravityIntegration.setup() + config = agent_config(tmp_path) + config.response_schema = { + "type": "object", + "properties": {"word": {"type": "string"}}, + "required": ["word"], + } + with cassette_transport("structured"): + async with Agent(config) as agent: + response = await agent.chat("Return the word pineapple using the required output schema.") + result = await response.structured_output() + assert result == {"word": "pineapple"} + chat = next(s for s in memory_logger.pop() if s["span_attributes"]["name"] == "antigravity.chat") + assert chat["output"] == result diff --git a/py/src/braintrust/integrations/antigravity/tracing.py b/py/src/braintrust/integrations/antigravity/tracing.py new file mode 100644 index 00000000..b204a12a --- /dev/null +++ b/py/src/braintrust/integrations/antigravity/tracing.py @@ -0,0 +1,320 @@ +"""Observe chat consumption without changing ChatResponse or its cursors. + +The subprocess reports execution steps and turn-level usage, not individual +model requests. This is partial agentic instrumentation: the spec's per-call +LLM spans and built-in tool return values cannot be recovered from this wire +protocol. Model steps are tasks; only the chat task owns aggregate usage. +The separate send/receive API is deliberately excluded from instrumentation. +""" + +import contextvars +import logging +import time +import weakref +from typing import Any + +from braintrust.integrations.utils import _extract_google_usage_metadata_metrics, _materialize_attachment +from braintrust.logger import start_span as _bt_start_span + + +logger = logging.getLogger(__name__) +_INSTRUMENTATION = "antigravity-auto" +# Metadata allowlist: model, tools, conversation_id, trajectory_id, step_index. +# Function definitions allow only name, description and parameters. Never log +# AgentConfig wholesale: endpoints and other config fields contain credentials. +_active_chat: contextvars.ContextVar[Any] = contextvars.ContextVar("braintrust_antigravity_chat", default=None) +_agent_config: contextvars.ContextVar[Any] = contextvars.ContextVar("braintrust_antigravity_config", default=None) +_pending: weakref.WeakKeyDictionary[Any, Any] = weakref.WeakKeyDictionary() +_tool_chats: weakref.WeakKeyDictionary[Any, Any] = weakref.WeakKeyDictionary() + + +def start_span(*args, **kwargs): + internal = dict(kwargs.get("internal") or {}) + internal.setdefault("instrumentation", _INSTRUMENTATION) + kwargs["internal"] = internal + return _bt_start_span(*args, **kwargs) + + +def _finish_pending(conversation, error=None): + if conversation is None: + return + state_ref = _pending.pop(conversation, None) + state = state_ref() if state_ref is not None else None + if state is not None and not state.done: + state.finish(error) + + +def _prompt_messages(prompt): + parts = [] + for part in prompt if isinstance(prompt, (list, tuple)) else [prompt]: + if isinstance(part, str): + parts.append({"type": "text", "text": part}) + elif hasattr(part, "data") and hasattr(part, "mime_type"): + resolved = _materialize_attachment(part.data, mime_type=part.mime_type) + if resolved is not None: + if part.mime_type.startswith("image/"): + parts.append({"type": "image_url", "image_url": {"url": resolved.attachment}}) + else: + parts.append( + {"type": "file", "file": {"file_data": resolved.attachment, "filename": resolved.filename}} + ) + else: + parts.append(part) + elif part is not None: + parts.append(part) + return [{"role": "user", "content": parts}] + + +class _ChatState: + def __init__(self, conversation, prompt): + self.conversation = weakref.ref(conversation) + self.started = time.monotonic() + messages = _prompt_messages(prompt) + metadata = {} + config = _agent_config.get() + if config is not None: + instructions = config.system_instructions + if instructions: + messages.insert(0, {"role": "system", "content": instructions}) + model = getattr(config, "model", None) + if isinstance(model, str): + metadata["model"] = model + capabilities = getattr(config, "capabilities", None) + enabled_tools = getattr(capabilities, "enabled_tools", None) + if enabled_tools: + metadata["tools"] = [{"type": getattr(tool, "value", tool)} for tool in enabled_tools] + self.client_tool_names: set[str] = set() + tool_runner = getattr(conversation.connection, "_tool_runner", None) + if tool_runner is not None: + self.client_tool_names.update(tool_runner.tool_names) + tools = metadata.get("tools", []) + try: + from google.antigravity.connections.local.interactions_config_converter import ( + callable_to_function_tool_dict, + ) + + for tool in tool_runner.tools.values(): + definition = callable_to_function_tool_dict(tool, tool_runner=tool_runner) + tools.append( + { + "type": "function", + "function": { + k: definition[k] for k in ("name", "description", "parameters") if k in definition + }, + } + ) + except Exception: + logger.debug("Could not read Antigravity tool definitions", exc_info=True) + if tools: + metadata["tools"] = tools + self.span = start_span(name="antigravity.chat", type="task", input=messages, metadata=metadata) + self.steps: dict[Any, Any] = {} + self.text: list[str] = [] + self.structured_output = None + self.done = False + self.sent = False + self.error_logged = False + self.first_token = False + if tool_runner is not None: + _tool_chats[tool_runner] = weakref.ref(self) + + def observe_step(self, step): + key = (step.trajectory_id, step.step_index) + if step.type == "FINISH" and step.status == "DONE" and step.structured_output is not None: + self.structured_output = step.structured_output + if step.source == "SYSTEM" and step.error: + self.span.log(error=step.error) + if step.source in ("USER", "SYSTEM") or step.type == "UNKNOWN": + return + # The SDK emits both step updates and a separate call notification + # for Python tools. ToolRunner.execute owns their spans and results. + if step.type == "TOOL_CALL": + if not step.tool_calls or all(call.name in self.client_tool_names for call in step.tool_calls): + return + entry = self.steps.get(key) + if entry is None: + call = step.tool_calls[0] if step.tool_calls else None + span = self.span.start_span( + name=getattr(call.name, "value", call.name) if call else f"antigravity.{step.type.value.lower()}", + type="tool" if call else "task", + input=call.args if call else None, + metadata={"trajectory_id": step.trajectory_id, "step_index": step.step_index}, + internal={"instrumentation": _INSTRUMENTATION}, + ) + entry = self.steps[key] = {"span": span, "done": False, "tool": call is not None} + if entry["done"]: + return + span = entry["span"] + if (step.content or step.thinking) and not entry["tool"]: + span.log(output={"role": "assistant", "content": step.content, "reasoning": step.thinking}) + if step.error: + span.log(error=step.error) + if step.status in ("DONE", "ERROR", "CANCELED"): + if step.structured_output is not None: + span.log(output=step.structured_output) + span.end() + entry["done"] = True + + def observe_chunk(self, chunk): + if self.done: + return + # Thought and Text both have text; only Text is conversational output. + from google.antigravity.types import Text + + if isinstance(chunk, Text) and chunk.text: + self.text.append(chunk.text) + if not self.first_token: + self.span.log(metrics={"time_to_first_token": time.monotonic() - self.started}) + self.first_token = True + + def finish(self, error=None): + # cancel() ends timing before the SDK cursor raises its cancellation + # exception. Preserve that exact exception if consumption observes it. + if error is not None and not self.error_logged: + self.span.log(error=error) + self.error_logged = True + if self.done: + return + self.done = True + output = ( + self.structured_output + if self.structured_output is not None + else [{"role": "assistant", "content": "".join(self.text)}] + ) + self.span.log(output=output) + conversation = self.conversation() + metrics = {} + metadata = {} + try: + if conversation is not None and self.sent: + metrics = _extract_google_usage_metadata_metrics(conversation.last_turn_usage) + metrics = { + k: v for k, v in metrics.items() if isinstance(v, int) and not isinstance(v, bool) and v >= 0 + } + metadata = {"conversation_id": conversation.conversation_id} + except Exception: + logger.debug("Could not read Antigravity turn usage", exc_info=True) + self.span.log(metrics=metrics, metadata=metadata) + for entry in self.steps.values(): + if not entry["done"]: + entry["span"].end() + entry["done"] = True + self.span.end() + + +class _ChatStream: + """Wrap only the upstream cursor; preserve the SDK's shared buffering.""" + + def __init__(self, stream, state): + self.stream = stream + self.state = state + self._finalizer = weakref.finalize(self, state.finish) + + def __aiter__(self): + return self + + async def __anext__(self): + token = _active_chat.set(self.state) + try: + self.state.span.set_current() + try: + chunk = await self.stream.__anext__() + finally: + self.state.span.unset_current() + try: + self.state.observe_chunk(chunk) + except Exception: + logger.debug("Could not trace Antigravity chunk", exc_info=True) + return chunk + except StopAsyncIteration: + self.state.finish() + raise + except BaseException as exc: + self.state.finish(exc) + raise + finally: + _active_chat.reset(token) + + async def aclose(self): + try: + await self.stream.aclose() + finally: + self.state.finish() + + +async def _chat_wrapper(wrapped, instance, args, kwargs): + prompt = args[0] if args else kwargs.get("prompt") + _finish_pending(instance) + state = None + try: + state = _ChatState(instance, prompt) + _pending[instance] = weakref.ref(state) + except Exception: + logger.debug("Could not start Antigravity trace", exc_info=True) + try: + response = await wrapped(*args, **kwargs) + except BaseException as exc: + if state is not None: + state.finish(exc) + raise + try: + if state is None: + return response + state.sent = True + response._chunk_stream = _ChatStream(response._chunk_stream, state) + except Exception: + if state is not None: + state.finish() + logger.debug("Could not instrument Antigravity response", exc_info=True) + return response + + +async def _receive_steps_wrapper(wrapped, instance, args, kwargs): + state = _active_chat.get() + async for step in wrapped(*args, **kwargs): + if state is not None and not state.done: + try: + state.observe_step(step) + except Exception: + logger.debug("Could not trace Antigravity step", exc_info=True) + yield step + + +async def _lifecycle_wrapper(wrapped, instance, args, kwargs): + error = None + try: + return await wrapped(*args, **kwargs) + except BaseException as exc: + error = exc + raise + finally: + _finish_pending(instance, error) + + +async def _agent_chat_wrapper(wrapped, instance, args, kwargs): + token = _agent_config.set(instance._config) + try: + return await wrapped(*args, **kwargs) + finally: + _agent_config.reset(token) + + +async def _agent_exit_wrapper(wrapped, instance, args, kwargs): + return await _lifecycle_wrapper(wrapped, instance._conversation, args, kwargs) + + +async def _tool_execute_wrapper(wrapped, instance, args, kwargs): + state_ref = _tool_chats.get(instance) + state = state_ref() if state_ref is not None else None + if state is None or state.done: + return await wrapped(*args, **kwargs) + name = args[0] if args else kwargs.get("tool_name") + tool_input = dict(kwargs) + if not args: + tool_input.pop("tool_name", None) + with state.span.start_span( + name=name, type="tool", input=tool_input, internal={"instrumentation": _INSTRUMENTATION} + ) as span: + result = await wrapped(*args, **kwargs) + span.log(output=result) + return result diff --git a/py/src/braintrust/integrations/auto_test_scripts/test_auto_antigravity.py b/py/src/braintrust/integrations/auto_test_scripts/test_auto_antigravity.py new file mode 100644 index 00000000..6aba64d2 --- /dev/null +++ b/py/src/braintrust/integrations/auto_test_scripts/test_auto_antigravity.py @@ -0,0 +1,40 @@ +"""Antigravity setup is idempotent across both provider import orders.""" + +import asyncio +import importlib +import os +import sys +import tempfile + +from braintrust.auto import auto_instrument +from braintrust.integrations.test_utils import autoinstrument_test_context + + +provider = None +if os.environ.get("BRAINTRUST_ANTIGRAVITY_IMPORT_ORDER") == "before": + provider = importlib.import_module("google.antigravity") +else: + assert "google.antigravity" not in sys.modules + + +async def main(): + assert "antigravity" not in auto_instrument(antigravity=False) + assert auto_instrument()["antigravity"] is True + assert auto_instrument()["antigravity"] is True + sdk = provider or importlib.import_module("google.antigravity") + from braintrust.integrations.antigravity._test_transport import cassette_transport + + with tempfile.TemporaryDirectory() as workspace: + with autoinstrument_test_context("chat", integration="antigravity", use_vcr=False) as memory_logger: + with cassette_transport("chat"): + config = sdk.LocalAgentConfig(model="gemini-3.8-flash", app_data_dir=workspace).lightweight() + async with sdk.Agent(config) as agent: + response = await agent.chat("Reply with exactly: antigravity tracing complete") + assert "antigravity tracing complete" in (await response.text()).lower() + spans = memory_logger.pop() + assert len([s for s in spans if s.get("span_attributes", {}).get("name") == "antigravity.chat"]) == 1 + assert all(s["context"]["span_origin"]["instrumentation"]["name"] == "antigravity-auto" for s in spans) + + +asyncio.run(main()) +print("SUCCESS")