File size: 7,459 Bytes
d7b3d84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
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()

	@tools.registry.action('Apply CSS blur filter to entire page content')
	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)

	@tools.registry.action('Remove CSS blur filter from page')
	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.
	@tools.registry.action('Fill in a specific field for a website using value from 1Password vault')
	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())