Spaces:
Sleeping
Sleeping
| import os | |
| from onepassword.client import Client | |
| from browser_use import ActionResult, Agent, Browser, ChatOpenAI, Tools | |
| from browser_use.browser.session import BrowserSession | |
| """ | |
| Use Case: Securely log into a website using credentials stored in 1Password vault. | |
| - Use fill_field action to fill in username and password fields with values retrieved from 1Password. The LLM never sees the actual credentials. | |
| - Use blur_page and unblur_page actions to visually obscure sensitive information on the page while filling in credentials for extra security. | |
| **SETUP** | |
| How to setup 1Password with Browser Use | |
| - Get Individual Plan for 1Password | |
| - Go to the Home page and click “New Vault” | |
| - Add the credentials you need for any websites you want to log into | |
| - Go to “Developer” tab, navigate to “Directory” and create a Service Account | |
| - Give the service account access to the vault | |
| - Copy the Service Account Token and set it as environment variable OP_SERVICE_ACCOUNT_TOKEN | |
| - Install the onepassword package: pip install onepassword-sdk | |
| Note: In this example, we assume that you created a vault named "prod-secrets" and added an item named "X" with fields "username" and "password". | |
| """ | |
| async def main(): | |
| # Gets your service account token from environment variable | |
| token = os.getenv('OP_SERVICE_ACCOUNT_TOKEN') | |
| # Authenticate with 1Password | |
| op_client = await Client.authenticate(auth=token, integration_name='Browser Use Secure Login', integration_version='v1.0.0') | |
| # Initialize tools | |
| tools = Tools() | |
| async def blur_page(browser_session: BrowserSession): | |
| """ | |
| Applies CSS blur filter directly to document.body to obscure all page content. | |
| The blur will remain until unblur_page is called. | |
| DOM remains accessible for element finding while page is visually blurred. | |
| """ | |
| try: | |
| # Get CDP session | |
| cdp_session = await browser_session.get_or_create_cdp_session() | |
| # Apply blur filter to document.body | |
| result = await cdp_session.cdp_client.send.Runtime.evaluate( | |
| params={ | |
| 'expression': """ | |
| (function() { | |
| // Check if already blurred | |
| if (document.body.getAttribute('data-page-blurred') === 'true') { | |
| console.log('[BLUR] Page already blurred'); | |
| return true; | |
| } | |
| // Apply CSS blur filter to body | |
| document.body.style.filter = 'blur(15px)'; | |
| document.body.style.webkitFilter = 'blur(15px)'; // Safari support | |
| document.body.style.transition = 'filter 0.3s ease'; | |
| document.body.setAttribute('data-page-blurred', 'true'); | |
| console.log('[BLUR] Applied CSS blur to page'); | |
| return true; | |
| })(); | |
| """, | |
| 'returnByValue': True, | |
| }, | |
| session_id=cdp_session.session_id, | |
| ) | |
| success = result.get('result', {}).get('value', False) | |
| if success: | |
| print('[BLUR] Applied CSS blur to page') | |
| return ActionResult(extracted_content='Successfully applied CSS blur to page', include_in_memory=True) | |
| else: | |
| return ActionResult(error='Failed to apply blur', include_in_memory=True) | |
| except Exception as e: | |
| print(f'[BLUR ERROR] {e}') | |
| return ActionResult(error=f'Failed to blur page: {str(e)}', include_in_memory=True) | |
| async def unblur_page(browser_session: BrowserSession): | |
| """ | |
| Removes the CSS blur filter from document.body, restoring normal page visibility. | |
| """ | |
| try: | |
| # Get CDP session | |
| cdp_session = await browser_session.get_or_create_cdp_session() | |
| # Remove blur filter from body | |
| result = await cdp_session.cdp_client.send.Runtime.evaluate( | |
| params={ | |
| 'expression': """ | |
| (function() { | |
| if (document.body.getAttribute('data-page-blurred') !== 'true') { | |
| console.log('[BLUR] Page not blurred'); | |
| return false; | |
| } | |
| // Remove CSS blur filter | |
| document.body.style.filter = 'none'; | |
| document.body.style.webkitFilter = 'none'; | |
| document.body.removeAttribute('data-page-blurred'); | |
| console.log('[BLUR] Removed CSS blur from page'); | |
| return true; | |
| })(); | |
| """, | |
| 'returnByValue': True, | |
| }, | |
| session_id=cdp_session.session_id, | |
| ) | |
| removed = result.get('result', {}).get('value', False) | |
| if removed: | |
| print('[BLUR] Removed CSS blur from page') | |
| return ActionResult(extracted_content='Successfully removed CSS blur from page', include_in_memory=True) | |
| else: | |
| print('[BLUR] Page was not blurred') | |
| return ActionResult( | |
| extracted_content='Page was not blurred (may have already been removed)', include_in_memory=True | |
| ) | |
| except Exception as e: | |
| print(f'[BLUR ERROR] {e}') | |
| return ActionResult(error=f'Failed to unblur page: {str(e)}', include_in_memory=True) | |
| # LLM can call this action to use actors to fill in sensitive fields using 1Password values. | |
| async def fill_field(vault_name: str, item_name: str, field_name: str, browser_session: BrowserSession): | |
| """ | |
| Fills in a specific field for a website using the value from 1Password. | |
| Note: Use blur_page before calling this if you want visual security. | |
| """ | |
| try: | |
| # Resolve field value from 1Password | |
| field_value = await op_client.secrets.resolve(f'op://{vault_name}/{item_name}/{field_name}') | |
| # Get current page | |
| page = await browser_session.must_get_current_page() | |
| # Find and fill the element | |
| target_field = await page.must_get_element_by_prompt(f'{field_name} input field', llm) | |
| await target_field.fill(field_value) | |
| return ActionResult( | |
| extracted_content=f'Successfully filled {field_name} field for {vault_name}/{item_name}', include_in_memory=True | |
| ) | |
| except Exception as e: | |
| return ActionResult(error=f'Failed to fill {field_name} field: {str(e)}', include_in_memory=True) | |
| browser_session = Browser() | |
| llm = ChatOpenAI(model='o3') | |
| agent = Agent( | |
| task=""" | |
| Navigate to https://x.com/i/flow/login | |
| Wait for the page to load. | |
| Use fill_field action with vault_name='prod-secrets' and item_name='X' and field_name='username'. | |
| Click the Next button. | |
| Use fill_field action with vault_name='prod-secrets' and item_name='X' and field_name='password'. | |
| Click the Log in button. | |
| Give me the latest 5 tweets from the logged in user's timeline. | |
| **IMPORTANT** Use blur_page action if you anticipate filling sensitive fields. | |
| Only use unblur_page action after you see the logged in user's X timeline. | |
| Your priority is to keep the username and password hidden while filling sensitive fields. | |
| """, | |
| browser_session=browser_session, | |
| llm=llm, | |
| tools=tools, | |
| file_system_path='./agent_data', | |
| ) | |
| await agent.run() | |
| if __name__ == '__main__': | |
| import asyncio | |
| asyncio.run(main()) | |