diff --git a/skyvern/forge/sdk/routes/credentials.py b/skyvern/forge/sdk/routes/credentials.py index 612e5d46..1d29288a 100644 --- a/skyvern/forge/sdk/routes/credentials.py +++ b/skyvern/forge/sdk/routes/credentials.py @@ -1,5 +1,5 @@ import structlog -from fastapi import Body, Depends, HTTPException, Path, Query +from fastapi import BackgroundTasks, Body, Depends, HTTPException, Path, Query from skyvern.forge import app from skyvern.forge.prompts import prompt_engine @@ -34,6 +34,19 @@ from skyvern.forge.sdk.services.bitwarden import BitwardenService LOG = structlog.get_logger() +async def fetch_credential_item_background(item_id: str) -> None: + """ + Background task to fetch the recently added credential item from Bitwarden. + This triggers Bitwarden to sync the vault earlier so the next request does not have to wait for the sync. + """ + try: + LOG.info("Pre-fetching credential item from Bitwarden in background", item_id=item_id) + credential_item = await BitwardenService.get_credential_item(item_id) + LOG.info("Successfully fetched credential item from Bitwarden", item_id=item_id, name=credential_item.name) + except Exception as e: + LOG.exception("Failed to fetch credential item from Bitwarden in background", item_id=item_id, error=str(e)) + + async def parse_totp_code(content: str, organization_id: str) -> str | None: prompt = prompt_engine.load_prompt("parse-verification-code", content=content) code_resp = await app.SECONDARY_LLM_API_HANDLER( @@ -129,6 +142,7 @@ async def send_totp_code( include_in_schema=False, ) async def create_credential( + background_tasks: BackgroundTasks, data: CreateCredentialRequest = Body( ..., description="The credential data to create", @@ -170,6 +184,9 @@ async def create_credential( totp_type=data.credential.totp_type if hasattr(data.credential, "totp_type") else "none", ) + # Early resyncing the Bitwarden vault + background_tasks.add_task(fetch_credential_item_background, item_id) + if data.credential_type == CredentialType.PASSWORD: credential_response = PasswordCredentialResponse( username=data.credential.username,