From c50518befe163fd8ac8d81b7d3651e1e919a3511 Mon Sep 17 00:00:00 2001 From: rcholic Date: Mon, 29 Dec 2025 07:43:16 -0800 Subject: [PATCH 1/2] local storage first --- ...cloud_tracing_agent.py => local_tracing_agent.py} | 3 ++- pyproject.toml | 2 +- sentience/__init__.py | 2 +- sentience/tracer_factory.py | 12 ++++++++---- 4 files changed, 12 insertions(+), 7 deletions(-) rename examples/{cloud_tracing_agent.py => local_tracing_agent.py} (95%) diff --git a/examples/cloud_tracing_agent.py b/examples/local_tracing_agent.py similarity index 95% rename from examples/cloud_tracing_agent.py rename to examples/local_tracing_agent.py index 5c9dc25..5d30ba9 100644 --- a/examples/cloud_tracing_agent.py +++ b/examples/local_tracing_agent.py @@ -41,7 +41,8 @@ def main(): # If api_key is Pro/Enterprise, uses CloudTraceSink # If api_key is missing/invalid, falls back to local JsonlTraceSink run_id = "cloud-tracing-demo" - tracer = create_tracer(api_key=sentience_key, run_id=run_id) + # local storage tracer, is upload_tracer is True and api_key is provided, will upload to cloud + tracer = create_tracer(api_key=sentience_key, run_id=run_id, upload_trace=False) print(f"🆔 Run ID: {run_id}\n") diff --git a/pyproject.toml b/pyproject.toml index 390418d..2c0d3af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "sentienceapi" -version = "0.90.5" +version = "0.90.7" description = "Python SDK for Sentience AI Agent Browser Automation" readme = "README.md" requires-python = ">=3.11" diff --git a/sentience/__init__.py b/sentience/__init__.py index cc52e4a..a6a1d3f 100644 --- a/sentience/__init__.py +++ b/sentience/__init__.py @@ -70,7 +70,7 @@ ) from .wait import wait_for -__version__ = "0.90.5" +__version__ = "0.90.7" __all__ = [ # Core SDK diff --git a/sentience/tracer_factory.py b/sentience/tracer_factory.py index 2353f1c..57b61a5 100644 --- a/sentience/tracer_factory.py +++ b/sentience/tracer_factory.py @@ -23,6 +23,7 @@ def create_tracer( run_id: str | None = None, api_url: str | None = None, logger: SentienceLogger | None = None, + upload_trace: bool = False, ) -> Tracer: """ Create tracer with automatic tier detection. @@ -38,6 +39,9 @@ def create_tracer( run_id: Unique identifier for this agent run. If not provided, generates UUID. api_url: Sentience API base URL (default: https://api.sentienceapi.com) logger: Optional logger instance for logging file sizes and errors + upload_trace: Enable cloud trace upload (default: False). When True and api_key + is provided, traces will be uploaded to cloud. When False, traces + are saved locally only. Returns: Tracer configured with appropriate sink @@ -62,12 +66,12 @@ def create_tracer( if api_url is None: api_url = SENTIENCE_API_URL - # 0. Check for orphaned traces from previous crashes (if api_key provided) - if api_key: + # 0. Check for orphaned traces from previous crashes (if api_key provided and upload enabled) + if api_key and upload_trace: _recover_orphaned_traces(api_key, api_url) - # 1. Try to initialize Cloud Sink (Pro/Enterprise tier) - if api_key: + # 1. Try to initialize Cloud Sink (Pro/Enterprise tier) if upload enabled + if api_key and upload_trace: try: # Request pre-signed upload URL from backend response = requests.post( From 8ba163e1ce42ac930b3ec7b69ac69b856cee937f Mon Sep 17 00:00:00 2001 From: rcholic Date: Mon, 29 Dec 2025 07:53:30 -0800 Subject: [PATCH 2/2] fix tests --- tests/test_cloud_tracing.py | 16 ++++++++-------- tests/test_file_size_tracking.py | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/test_cloud_tracing.py b/tests/test_cloud_tracing.py index 23ee260..49b899a 100644 --- a/tests/test_cloud_tracing.py +++ b/tests/test_cloud_tracing.py @@ -250,7 +250,7 @@ def test_create_tracer_pro_tier_success(self, capsys): # Mock upload response mock_put.return_value = Mock(status_code=200) - tracer = create_tracer(api_key="sk_pro_test123", run_id="test-run") + tracer = create_tracer(api_key="sk_pro_test123", run_id="test-run", upload_trace=True) # Verify Pro tier message captured = capsys.readouterr() @@ -294,7 +294,7 @@ def test_create_tracer_api_forbidden_fallback(self, capsys): mock_post.return_value = mock_response with tempfile.TemporaryDirectory(): - tracer = create_tracer(api_key="sk_free_test123", run_id="test-run") + tracer = create_tracer(api_key="sk_free_test123", run_id="test-run", upload_trace=True) # Verify warning message captured = capsys.readouterr() @@ -315,7 +315,7 @@ def test_create_tracer_api_timeout_fallback(self, capsys): mock_post.side_effect = requests.exceptions.Timeout("Connection timeout") with tempfile.TemporaryDirectory(): - tracer = create_tracer(api_key="sk_test123", run_id="test-run") + tracer = create_tracer(api_key="sk_test123", run_id="test-run", upload_trace=True) # Verify warning message captured = capsys.readouterr() @@ -336,7 +336,7 @@ def test_create_tracer_api_connection_error_fallback(self, capsys): mock_post.side_effect = requests.exceptions.ConnectionError("Connection refused") with tempfile.TemporaryDirectory(): - tracer = create_tracer(api_key="sk_test123", run_id="test-run") + tracer = create_tracer(api_key="sk_test123", run_id="test-run", upload_trace=True) # Verify warning message captured = capsys.readouterr() @@ -371,7 +371,7 @@ def test_create_tracer_uses_constant_api_url(self): mock_post.return_value = mock_response mock_put.return_value = Mock(status_code=200) - tracer = create_tracer(api_key="sk_test123", run_id="test-run") + tracer = create_tracer(api_key="sk_test123", run_id="test-run", upload_trace=True) # Verify correct API URL was used (constant) assert mock_post.called @@ -395,7 +395,7 @@ def test_create_tracer_custom_api_url(self): mock_put.return_value = Mock(status_code=200) tracer = create_tracer( - api_key="sk_test123", run_id="test-run", api_url=custom_api_url + api_key="sk_test123", run_id="test-run", api_url=custom_api_url, upload_trace=True ) # Verify custom API URL was used @@ -415,7 +415,7 @@ def test_create_tracer_missing_upload_url_in_response(self, capsys): mock_post.return_value = mock_response with tempfile.TemporaryDirectory(): - tracer = create_tracer(api_key="sk_test123", run_id="test-run") + tracer = create_tracer(api_key="sk_test123", run_id="test-run", upload_trace=True) # Verify warning message captured = capsys.readouterr() @@ -463,7 +463,7 @@ def test_create_tracer_orphaned_trace_recovery(self, capsys): mock_put.return_value = Mock(status_code=200) # Create tracer - should trigger orphaned trace recovery - tracer = create_tracer(api_key="sk_test123", run_id="new-run-456") + tracer = create_tracer(api_key="sk_test123", run_id="new-run-456", upload_trace=True) # Verify recovery messages captured = capsys.readouterr() diff --git a/tests/test_file_size_tracking.py b/tests/test_file_size_tracking.py index a1cbc86..0d97aae 100644 --- a/tests/test_file_size_tracking.py +++ b/tests/test_file_size_tracking.py @@ -186,6 +186,7 @@ def test_create_tracer_passes_logger_to_cloud_sink(self, mock_requests): api_key="sk_test_key", run_id="test-logger", logger=mock_logger, + upload_trace=True, ) # Verify tracer was created