diff --git a/skyvern/forge/sdk/routes/agent_protocol.py b/skyvern/forge/sdk/routes/agent_protocol.py index 5fda3abbf..f5098a0dd 100644 --- a/skyvern/forge/sdk/routes/agent_protocol.py +++ b/skyvern/forge/sdk/routes/agent_protocol.py @@ -2947,25 +2947,37 @@ async def get_workflow_versions( @base_router.post( - "/workflows/{workflow_permanent_id}/browser_session/refresh", + "/workflows/{workflow_permanent_id}/browser_session/reset_profile", status_code=http_status.HTTP_204_NO_CONTENT, tags=["Workflows"], - summary="Refresh persisted browser session", + summary="Reset persisted browser profile", description=( - "Clear the persisted browser session for a workflow that uses `Save & Reuse Session`. " - "The next run will start from a fresh browser state. Use when a saved session is corrupted." + "Clear the persisted browser profile for a workflow that uses `Save & Reuse Session`. " + "The next run will start from a fresh browser state. Use when a saved profile is corrupted." ), + operation_id="reset_workflow_browser_profile", responses={ - 204: {"description": "Successfully cleared persisted browser session"}, + 204: {"description": "Successfully cleared persisted browser profile"}, 404: {"description": "Workflow not found"}, + 500: {"description": "Storage deletion failed; retry"}, }, ) +@base_router.post( + "/workflows/{workflow_permanent_id}/browser_session/reset_profile/", + status_code=http_status.HTTP_204_NO_CONTENT, + include_in_schema=False, +) +@base_router.post( + "/workflows/{workflow_permanent_id}/browser_session/refresh", + status_code=http_status.HTTP_204_NO_CONTENT, + include_in_schema=False, +) @base_router.post( "/workflows/{workflow_permanent_id}/browser_session/refresh/", status_code=http_status.HTTP_204_NO_CONTENT, include_in_schema=False, ) -async def refresh_workflow_browser_session( +async def reset_workflow_browser_profile( workflow_permanent_id: str = Path( ..., description="The permanent ID of the workflow. Starts with `wpid_`.", @@ -2973,14 +2985,14 @@ async def refresh_workflow_browser_session( ), current_org: Organization = Depends(org_auth_service.get_current_org), ) -> None: - analytics.capture("skyvern-oss-agent-workflow-browser-session-refresh") + analytics.capture("skyvern-oss-agent-workflow-browser-profile-reset") # Verify the workflow exists and belongs to the caller's organization. await app.WORKFLOW_SERVICE.get_workflow_by_permanent_id( workflow_permanent_id=workflow_permanent_id, organization_id=current_org.organization_id, ) LOG.info( - "Refreshing persisted browser session for workflow", + "Resetting persisted browser profile for workflow", organization_id=current_org.organization_id, workflow_permanent_id=workflow_permanent_id, ) @@ -2993,12 +3005,12 @@ async def refresh_workflow_browser_session( raise except Exception as exc: LOG.exception( - "Failed to refresh persisted browser session for workflow", + "Failed to reset persisted browser profile for workflow", organization_id=current_org.organization_id, workflow_permanent_id=workflow_permanent_id, ) raise SkyvernHTTPException( - message="Failed to clear the persisted browser session. Please retry the refresh operation.", + message="Failed to clear the persisted browser profile. Please retry the reset operation.", status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR, ) from exc diff --git a/tests/unit/forge/sdk/test_refresh_browser_session_route.py b/tests/unit/forge/sdk/test_reset_browser_profile_route.py similarity index 70% rename from tests/unit/forge/sdk/test_refresh_browser_session_route.py rename to tests/unit/forge/sdk/test_reset_browser_profile_route.py index b547d70dc..1875a93a9 100644 --- a/tests/unit/forge/sdk/test_refresh_browser_session_route.py +++ b/tests/unit/forge/sdk/test_reset_browser_profile_route.py @@ -1,4 +1,4 @@ -"""Tests for POST /workflows/{wpid}/browser_session/refresh.""" +"""Tests for POST /workflows/{wpid}/browser_session/reset_profile.""" from __future__ import annotations @@ -36,11 +36,11 @@ def _build_client(monkeypatch: pytest.MonkeyPatch) -> tuple[TestClient, AsyncMoc return TestClient(fastapi_app), get_workflow, delete_browser_session -def test_refresh_browser_session_clears_storage(monkeypatch: pytest.MonkeyPatch) -> None: +def test_reset_browser_profile_clears_storage(monkeypatch: pytest.MonkeyPatch) -> None: client, get_workflow, delete_browser_session = _build_client(monkeypatch) get_workflow.return_value = SimpleNamespace(workflow_permanent_id="wpid_123") - response = client.post("/v1/workflows/wpid_123/browser_session/refresh") + response = client.post("/v1/workflows/wpid_123/browser_session/reset_profile") assert response.status_code == 204 get_workflow.assert_awaited_once_with(workflow_permanent_id="wpid_123", organization_id="org_oss") @@ -50,22 +50,43 @@ def test_refresh_browser_session_clears_storage(monkeypatch: pytest.MonkeyPatch) ) -def test_refresh_browser_session_workflow_not_found(monkeypatch: pytest.MonkeyPatch) -> None: +def test_reset_browser_profile_workflow_not_found(monkeypatch: pytest.MonkeyPatch) -> None: client, get_workflow, delete_browser_session = _build_client(monkeypatch) get_workflow.side_effect = WorkflowNotFound(workflow_permanent_id="wpid_missing") - response = client.post("/v1/workflows/wpid_missing/browser_session/refresh") + response = client.post("/v1/workflows/wpid_missing/browser_session/reset_profile") assert response.status_code == 404 delete_browser_session.assert_not_awaited() -def test_refresh_browser_session_storage_failure_returns_500(monkeypatch: pytest.MonkeyPatch) -> None: +def test_reset_browser_profile_storage_failure_returns_500(monkeypatch: pytest.MonkeyPatch) -> None: client, get_workflow, delete_browser_session = _build_client(monkeypatch) get_workflow.return_value = SimpleNamespace(workflow_permanent_id="wpid_123") delete_browser_session.side_effect = RuntimeError("s3 AccessDenied") - response = client.post("/v1/workflows/wpid_123/browser_session/refresh") + response = client.post("/v1/workflows/wpid_123/browser_session/reset_profile") assert response.status_code == 500 assert "retry" in response.json()["detail"].lower() + + +@pytest.mark.parametrize( + "path", + [ + "/v1/workflows/wpid_123/browser_session/refresh", + "/v1/workflows/wpid_123/browser_session/refresh/", + "/v1/workflows/wpid_123/browser_session/reset_profile/", + ], +) +def test_alias_paths_still_work(monkeypatch: pytest.MonkeyPatch, path: str) -> None: + client, get_workflow, delete_browser_session = _build_client(monkeypatch) + get_workflow.return_value = SimpleNamespace(workflow_permanent_id="wpid_123") + + response = client.post(path) + + assert response.status_code == 204 + delete_browser_session.assert_awaited_once_with( + organization_id="org_oss", + workflow_permanent_id="wpid_123", + )