Trisha Tomy commited on
Commit
d116fe5
Β·
1 Parent(s): 6a0e448

generalised prompts + return formatted correctly

Browse files
app.py CHANGED
@@ -1,64 +1,138 @@
1
  import gevent.monkey
2
  gevent.monkey.patch_all(asyncio=True) # Keep this at the very top
3
 
4
- import asyncio # Keep this
5
  from flask import Flask, request, jsonify
6
  from proxy_lite import Runner, RunnerConfig
7
  import os
8
  import logging
 
 
9
 
10
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
11
  logger = logging.getLogger(__name__)
12
 
13
  app = Flask(__name__)
14
 
15
- _runner = None
16
 
17
- async def initialize_runner():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  global _runner
19
- if _runner is None:
20
- logger.info("Initializing Proxy-lite Runner...")
21
-
22
- hf_api_token = os.environ.get("HF_API_TOKEN")
23
- if not hf_api_token:
24
- logger.error("HF_API_TOKEN environment variable not set. Cannot initialize Runner.")
25
- raise ValueError("HF_API_TOKEN environment variable not set. Please set it as a Space secret.")
26
-
27
- config = RunnerConfig.from_dict({
28
- "environment": {
29
- "name": "webbrowser",
30
- # Set homepage to Salesforce's generic login URL to avoid premature waits for target page elements.
31
- "homepage": "https://login.salesforce.com/",
32
- "headless": False, # Keep this False for local testing
33
- "launch_args": ["--no-sandbox", "--disable-setuid-sandbox"],
34
- "screenshot_delay": 0.5, # Reduced for faster debugging cycles
35
- "include_html": True,
36
- "include_poi_text": True,
37
- },
38
- "solver": {
39
- "name": "simple",
40
- "agent": {
41
- "name": "proxy_lite",
42
- "client": {
43
- "name": "convergence",
44
- "model_id": "convergence-ai/proxy-lite-3b",
45
- "api_base": "https://convergence-ai-demo-api.hf.space/v1",
46
- "api_key": hf_api_token
47
- }
48
- }
49
- },
50
- "environment_timeout": 1800.0,
51
- "action_timeout": 1800.0,
52
- "task_timeout": 18000.0,
53
- "max_steps": 150,
54
- "logger_level": "DEBUG",
55
- })
56
-
57
- logger.info(f"DEBUG: app.py - Initializing Runner with environment_timeout: {config.environment_timeout} seconds")
58
- logger.info(f"DEBUG: app.py - Full config used: {config.model_dump_json(indent=2)}")
59
-
60
- _runner = Runner(config=config)
61
- logger.info("Proxy-lite Runner initialized successfully.")
 
 
 
 
 
 
 
 
 
 
 
 
62
  return _runner
63
 
64
 
@@ -66,12 +140,18 @@ async def initialize_runner():
66
  async def run_proxy_task_endpoint():
67
  data = request.json
68
  request_task_instruction = data.get('task')
 
69
 
70
  if not request_task_instruction:
71
  logger.warning("Received request without 'task' field. Returning 400.")
72
  return jsonify({"error": "No 'task' provided in request body"}), 400
 
 
 
 
73
 
74
  logger.info(f"Received user request task: '{request_task_instruction}'")
 
75
 
76
  salesforce_username = os.environ.get("SALESFORCE_USERNAME")
77
  salesforce_password = os.environ.get("SALESFORCE_PASSWORD")
@@ -80,54 +160,163 @@ async def run_proxy_task_endpoint():
80
  logger.error("Salesforce credentials (SALESFORCE_USERNAME, SALESFORCE_PASSWORD) environment variables not set.")
81
  return jsonify({"error": "Salesforce credentials not configured. Please set SALESFORCE_USERNAME and SALESFORCE_PASSWORD as Space secrets."}), 500
82
 
83
- # Define the specific Account Forecast Settings URL
84
- account_forecast_url = "https://dwd000006jia1mae.lightning.force.com/lightning/setup/AccountForecastSettings/home"
85
-
86
- # Define the tool code block to open a new tab and navigate after login
87
- # Using a raw f-string for multiline tool code block
88
- tool_code_block_new_tab = fr"""
89
- <tool_code>
90
- await browser.open_new_tab_and_go_to(url='{account_forecast_url}')
91
- </tool_code>
92
- """
93
-
94
- # Refined agent_task instruction to be sequential and robust to Salesforce redirects
95
- agent_task = f"""
96
- **Task Instructions for Proxy Lite Agent:**
97
- 1. **Start on Login Page:** Navigate to the Salesforce login page.
98
- 2. **Perform Login:** Log in to Salesforce using the provided username '{salesforce_username}' and password '{salesforce_password}'. Ensure all login fields are filled and the 'Log In' button is clicked.
99
- 3. **Handle Post-Login Redirect:** After clicking the 'Log In' button:
100
- * Observe the current URL. If the URL has changed from the initial login domain (e.g., from `login.salesforce.com` or `my.salesforce.com`) **immediately execute the following tool code block to open a new tab and navigate directly to the Account Forecast Settings page (`{account_forecast_url}`) to bypass any persistent loading issues or internal redirects:**
101
- {tool_code_block_new_tab.strip()}
102
- 4. **Confirm Target Page Load:** After successfully navigating to '{account_forecast_url}' (either directly after login or via the new tab strategy), ensure the page is fully loaded and stable. This means no loading spinners should be visible, and the main content for 'Account Forecast Settings' (like a clear heading, relevant toggles, or data tables) should be present and interactive.
103
- 5. **Execute Main Task:** Once the Account Forecast Settings page is confirmed loaded and stable, proceed with the original user request: {request_task_instruction}.
104
- 6. **Report Final Status:** Report the final status of the requested action, confirming both successful login and complete page load of the Account Forecast Settings.
105
- """
106
-
107
- logger.info(f"Executing agent task (truncated for log): '{agent_task[:500]}...'")
108
 
109
  try:
110
- runner = await initialize_runner()
111
- result = await runner.run(agent_task)
 
 
 
112
 
113
- logger.info(f"Proxy-lite task completed. Output (truncated for log): {result[:500]}...")
114
- return jsonify({"output": result})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  except Exception as e:
116
- logger.exception(f"Error processing Salesforce task: {e}")
117
- return jsonify({"error": f"An error occurred: {str(e)}. Check logs for details."}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  @app.route('/')
120
  def root():
121
  logger.info("Root endpoint accessed.")
122
  return "Proxy-lite API is running. Send POST requests to /run_proxy_task with a 'task' in JSON body."
123
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  if __name__ == '__main__':
125
- # It is crucial to set HF_API_TOKEN as an environment variable (e.g., in a .env file or directly)
126
- # for local testing as well, otherwise initialize_runner will fail.
127
  if not os.environ.get("HF_API_TOKEN"):
128
  logger.error("HF_API_TOKEN environment variable is not set. Please set it for local testing.")
129
- # Removed exit(1) to allow the Flask app to start for basic connectivity checks,
130
- # but runner initialization will still fail if token is missing.
131
- # For full functionality, the token is essential.
132
- logger.info("Starting Flask development server on 0.0.0.0:7860...")
133
- app.run(host='0.0.0.0', port=7860, debug=True)
 
1
  import gevent.monkey
2
  gevent.monkey.patch_all(asyncio=True) # Keep this at the very top
3
 
4
+ import asyncio
5
  from flask import Flask, request, jsonify
6
  from proxy_lite import Runner, RunnerConfig
7
  import os
8
  import logging
9
+ from datetime import datetime
10
+ from playwright.async_api import async_playwright, TimeoutError as PlaywrightTimeoutError
11
 
12
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
13
  logger = logging.getLogger(__name__)
14
 
15
  app = Flask(__name__)
16
 
17
+ _runner = None
18
 
19
+ async def perform_hardcoded_salesforce_login_and_get_cookies(username, password, login_url, target_url):
20
+ logger.info("Attempting hardcoded Salesforce login with Playwright to obtain cookies...")
21
+ async with async_playwright() as p:
22
+ browser = await p.chromium.launch(headless=True, args=["--no-sandbox", "--disable-setuid-sandbox"])
23
+ context = await browser.new_context()
24
+ page = await context.new_page()
25
+
26
+ try:
27
+ await page.goto(login_url, wait_until="domcontentloaded", timeout=60000)
28
+ logger.info(f"Playwright: Navigated to Salesforce login page: {page.url}")
29
+
30
+ await page.fill("#username", username)
31
+ await page.fill("#password", password)
32
+ await page.click("#Login")
33
+ logger.info("Playwright: Filled credentials and clicked Login. Waiting for post-login state...")
34
+
35
+ try:
36
+ await page.wait_for_url(lambda url: "login.salesforce.com" not in url and "unauthorized" not in url.lower(), timeout=60000)
37
+ logger.info(f"Playwright: Successfully redirected from login page. Current URL: {page.url}")
38
+ await page.wait_for_selector('button[title="App Launcher"]', timeout=30000)
39
+ logger.info("Playwright: Main Salesforce Lightning UI (e.g., App Launcher) detected after login.")
40
+
41
+ except PlaywrightTimeoutError:
42
+ logger.error(f"Playwright: Did not detect main UI or expected URL change within timeout after login. Current URL: {page.url}. Login might have failed or stuck on a redirect loop.")
43
+ raise Exception("Salesforce login redirection failed or main UI not detected.")
44
+
45
+ logger.info(f"Playwright: Navigating to target URL: {target_url} to ensure all relevant cookies are captured.")
46
+ await page.goto(target_url, wait_until="domcontentloaded", timeout=60000)
47
+
48
+ try:
49
+ # Wait for generic Salesforce setup page elements to load
50
+ await page.wait_for_selector('.setupPage, .slds-page-header, .slds-card, [data-aura-class*="setup"], .forcePageBlockSectionView', timeout=30000)
51
+ logger.info("Playwright: Detected Salesforce setup page elements loaded successfully.")
52
+ except PlaywrightTimeoutError:
53
+ logger.warning("Playwright: Specific setup page elements not found. Trying generic page load check...")
54
+ try:
55
+ # Fallback: wait for page to reach network idle state
56
+ await page.wait_for_load_state("networkidle", timeout=10000)
57
+ logger.info("Playwright: Page reached network idle state - proceeding with task.")
58
+ except PlaywrightTimeoutError:
59
+ logger.info("Playwright: Page load validation timed out, but continuing as page may still be functional.")
60
+
61
+ await asyncio.sleep(2)
62
+ logger.info(f"Playwright: Successfully navigated to and confirmed content on {page.url}")
63
+
64
+ cookies = await context.cookies()
65
+ logger.info(f"Playwright: Extracted {len(cookies)} cookies after successful login and navigation.")
66
+ return cookies
67
+
68
+ except PlaywrightTimeoutError as e:
69
+ logger.error(f"Playwright login/navigation failed (Timeout): {e}. Current URL: {page.url}")
70
+ raise
71
+ except Exception as e:
72
+ logger.error(f"Playwright login/navigation failed (General Error): {e}. Current URL: {page.url}")
73
+ raise
74
+ finally:
75
+ if browser:
76
+ await browser.close()
77
+
78
+
79
+ async def initialize_runner_with_cookies(cookies: list, target_url: str):
80
  global _runner
81
+ logger.info("Initializing Proxy-lite Runner with provided cookies...")
82
+
83
+ hf_api_token = os.environ.get("HF_API_TOKEN")
84
+ if not hf_api_token:
85
+ logger.error("HF_API_TOKEN environment variable not set. Cannot initialize Runner.")
86
+ raise ValueError("HF_API_TOKEN environment variable not set. Please set it as a Space secret.")
87
+
88
+ config_dict = {
89
+ "environment": {
90
+ "name": "webbrowser",
91
+ "homepage": "about:blank", # Safe startup, we'll open new tab programmatically
92
+ "headless": False,
93
+ "launch_args": ["--no-sandbox", "--disable-setuid-sandbox"],
94
+ "screenshot_delay": 0.5,
95
+ "include_html": True,
96
+ "include_poi_text": True,
97
+ "record_pois": True,
98
+ "viewport_width": 1280,
99
+ "viewport_height": 720,
100
+ "browserbase_timeout": 7200,
101
+ "keep_original_image": False,
102
+ "no_pois_in_image": False,
103
+ "initial_cookies": cookies
104
+ },
105
+ "solver": {
106
+ "name": "simple",
107
+ "agent": {
108
+ "name": "proxy_lite", # Corrected as per previous error
109
+ "client": {
110
+ "name": "convergence",
111
+ "model_id": "convergence-ai/proxy-lite-3b",
112
+ "api_base": "https://convergence-ai-demo-api.hf.space/v1",
113
+ "api_key": hf_api_token,
114
+ "http_timeout": 50.0,
115
+ "http_concurrent_connections": 50,
116
+ },
117
+ "history_messages_limit": {
118
+ "screenshot": 1
119
+ },
120
+ "history_messages_include": None,
121
+ }
122
+ },
123
+ "environment_timeout": 1800.0,
124
+ "action_timeout": 1800.0,
125
+ "task_timeout": 18000.0,
126
+ "max_steps": 150,
127
+ "logger_level": "DEBUG",
128
+ "save_every_step": True,
129
+ "detailed_logger_name": False
130
+ }
131
+ config = RunnerConfig.from_dict(config_dict)
132
+
133
+ logger.info(f"DEBUG: app.py - Initializing Proxy-lite Runner with config (cookies to be injected).")
134
+ _runner = Runner(config=config)
135
+ logger.info("Proxy-lite Runner initialized successfully with injected cookies.")
136
  return _runner
137
 
138
 
 
140
  async def run_proxy_task_endpoint():
141
  data = request.json
142
  request_task_instruction = data.get('task')
143
+ target_url = data.get('url')
144
 
145
  if not request_task_instruction:
146
  logger.warning("Received request without 'task' field. Returning 400.")
147
  return jsonify({"error": "No 'task' provided in request body"}), 400
148
+
149
+ if not target_url:
150
+ logger.warning("Received request without 'url' field. Returning 400.")
151
+ return jsonify({"error": "No 'url' provided in request body"}), 400
152
 
153
  logger.info(f"Received user request task: '{request_task_instruction}'")
154
+ logger.info(f"Target URL: '{target_url}'")
155
 
156
  salesforce_username = os.environ.get("SALESFORCE_USERNAME")
157
  salesforce_password = os.environ.get("SALESFORCE_PASSWORD")
 
160
  logger.error("Salesforce credentials (SALESFORCE_USERNAME, SALESFORCE_PASSWORD) environment variables not set.")
161
  return jsonify({"error": "Salesforce credentials not configured. Please set SALESFORCE_USERNAME and SALESFORCE_PASSWORD as Space secrets."}), 500
162
 
163
+ salesforce_login_url = "https://login.salesforce.com/"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
  try:
166
+ logger.info("Executing hardcoded login via Playwright to get session cookies...")
167
+ session_cookies = await perform_hardcoded_salesforce_login_and_get_cookies(
168
+ salesforce_username, salesforce_password, salesforce_login_url, target_url
169
+ )
170
+ logger.info(f"Successfully obtained {len(session_cookies)} cookies. These will be injected into the agent's browser.")
171
 
172
+ runner = await initialize_runner_with_cookies(session_cookies, target_url)
173
+ logger.info("Proxy-lite Runner initialized with pre-set cookies.")
174
+
175
+ logger.info("Agent will use mandatory new tab tool to bypass loading issues.")
176
+
177
+ # MANDATORY new tab navigation task - this is critical to avoid loading issues
178
+ agent_task = f"""
179
+ CRITICAL FIRST STEP - MANDATORY:
180
+ Your VERY FIRST action must be to use the open_new_tab_and_go_to tool to navigate to {target_url}
181
+
182
+ DO NOT skip this step. DO NOT use goto. You MUST use: open_new_tab_and_go_to(url='{target_url}')
183
+
184
+ This is necessary because direct navigation to this URL gets stuck loading. The new tab approach bypasses this issue.
185
+
186
+ STEP 1: Use open_new_tab_and_go_to(url='{target_url}')
187
+ STEP 2: Wait for the page to be fully loaded (no loading spinners visible)
188
+ STEP 3: {request_task_instruction}
189
+
190
+ Report success/failure for each step.
191
+ """
192
+
193
+ logger.info("Executing agent task with mandatory new tab navigation...")
194
+ result = await runner.run(task=agent_task)
195
+
196
+ # Extract the actual result value from the Run object
197
+ if hasattr(result, 'value') and result.value:
198
+ task_result = str(result.value)
199
+ elif hasattr(result, 'result') and result.result:
200
+ task_result = str(result.result)
201
+ else:
202
+ task_result = str(result)
203
+
204
+ logger.info(f"Proxy-lite task completed. Output (truncated for log): {task_result[:500]}...")
205
+
206
+ # Structure response for LWC integration
207
+ response = {
208
+ "status": "success",
209
+ "message": "Task completed successfully",
210
+ "data": {
211
+ "task_result": task_result,
212
+ "steps_completed": [
213
+ "Hardcoded Salesforce login completed",
214
+ "Browser session initialized with cookies",
215
+ "New tab navigation executed",
216
+ "Target Salesforce setup page accessed",
217
+ "Task execution completed successfully"
218
+ ],
219
+ "environment": {
220
+ "target_url": target_url,
221
+ "cookies_count": len(session_cookies),
222
+ "navigation_method": "new_tab_bypass"
223
+ }
224
+ },
225
+ "timestamp": datetime.now().isoformat(),
226
+ "task_request": request_task_instruction
227
+ }
228
+
229
+ return jsonify(response)
230
+
231
+ except PlaywrightTimeoutError as e:
232
+ logger.exception(f"Playwright timeout during login/navigation: {e}")
233
+ error_response = {
234
+ "status": "error",
235
+ "error_type": "navigation_timeout",
236
+ "message": "Page loading timed out during login or navigation",
237
+ "data": {
238
+ "error_details": str(e),
239
+ "suggested_action": "Retry the request - network issues may be temporary",
240
+ "steps_completed": ["Login attempted", "Navigation failed due to timeout"]
241
+ },
242
+ "timestamp": datetime.now().isoformat(),
243
+ "task_request": request_task_instruction
244
+ }
245
+ return jsonify(error_response), 500
246
+
247
+ except ValueError as e:
248
+ logger.exception(f"Configuration error: {e}")
249
+ error_response = {
250
+ "status": "error",
251
+ "error_type": "configuration_error",
252
+ "message": "System configuration issue",
253
+ "data": {
254
+ "error_details": str(e),
255
+ "suggested_action": "Check environment variables and system configuration",
256
+ "steps_completed": ["Configuration validation failed"]
257
+ },
258
+ "timestamp": datetime.now().isoformat(),
259
+ "task_request": request_task_instruction
260
+ }
261
+ return jsonify(error_response), 500
262
+
263
  except Exception as e:
264
+ logger.exception(f"Unexpected error processing Salesforce task: {e}")
265
+ error_response = {
266
+ "status": "error",
267
+ "error_type": "unexpected_error",
268
+ "message": "An unexpected error occurred during task execution",
269
+ "data": {
270
+ "error_details": str(e),
271
+ "error_class": type(e).__name__,
272
+ "suggested_action": "Check logs for detailed error information and retry",
273
+ "steps_completed": ["Login attempted", "Error occurred during execution"]
274
+ },
275
+ "timestamp": datetime.now().isoformat(),
276
+ "task_request": request_task_instruction
277
+ }
278
+ return jsonify(error_response), 500
279
 
280
  @app.route('/')
281
  def root():
282
  logger.info("Root endpoint accessed.")
283
  return "Proxy-lite API is running. Send POST requests to /run_proxy_task with a 'task' in JSON body."
284
 
285
+ @app.route('/health', methods=['GET'])
286
+ def health_check():
287
+ """Health check endpoint for monitoring and debugging"""
288
+ logger.info("Health check endpoint accessed.")
289
+
290
+ # Check environment variables
291
+ env_status = {
292
+ "HF_API_TOKEN": "βœ“" if os.environ.get("HF_API_TOKEN") else "βœ—",
293
+ "SALESFORCE_USERNAME": "βœ“" if os.environ.get("SALESFORCE_USERNAME") else "βœ—",
294
+ "SALESFORCE_PASSWORD": "βœ“" if os.environ.get("SALESFORCE_PASSWORD") else "βœ—"
295
+ }
296
+
297
+ health_response = {
298
+ "status": "healthy",
299
+ "message": "Proxy-lite API is running",
300
+ "environment_variables": env_status,
301
+ "endpoints": {
302
+ "POST /run_proxy_task": "Execute Salesforce automation tasks (requires 'task' and 'url' parameters)",
303
+ "GET /health": "Health check and status",
304
+ "GET /": "API information"
305
+ },
306
+ "supported_pages": [
307
+ "Warranty Lifecycle Management",
308
+ "Account Forecasting Settings",
309
+ "Sales Agreements",
310
+ "Account Manager Targets",
311
+ "Any Salesforce Setup page"
312
+ ],
313
+ "timestamp": datetime.now().isoformat()
314
+ }
315
+
316
+ return jsonify(health_response)
317
+
318
  if __name__ == '__main__':
 
 
319
  if not os.environ.get("HF_API_TOKEN"):
320
  logger.error("HF_API_TOKEN environment variable is not set. Please set it for local testing.")
321
+ logger.info("Starting Flask development server on 0.0.0.0:6101...")
322
+ app.run(host='0.0.0.0', port=6101, debug=True)
 
 
 
src/proxy_lite/agents/proxy_lite_agent.py CHANGED
@@ -13,8 +13,8 @@ You were developed by Convergence AI.
13
  The user will instuct you to perform a task.
14
  You will be shown a screen as well as relevant interactable elements highlighted by mark_ids and you will be given a set of tools to use to perform the task.
15
  You should make observations about the screen, putting them in <observation></observation> tags.
16
- You should then reason about what needs to be done to complete the task, putting your thoughts in <thinking></thinking> tags.
17
- You should then use the tools to perform the task, putting the tool calls in <tool_call></tool_call> tags.
18
  """ # noqa: E501
19
 
20
  MAX_MESSAGES_FOR_CONTEXT_WINDOW = {
 
13
  The user will instuct you to perform a task.
14
  You will be shown a screen as well as relevant interactable elements highlighted by mark_ids and you will be given a set of tools to use to perform the task.
15
  You should make observations about the screen, putting them in <observation></observation> tags.
16
+ You should then reason about what needs to be done, but follow user instructions as first priority, to complete the task, putting your thoughts in <thinking></thinking> tags.
17
+ You should then use the tools to perform the task, but follow user instructions as first priority, putting the tool calls in <tool_call></tool_call> tags.
18
  """ # noqa: E501
19
 
20
  MAX_MESSAGES_FOR_CONTEXT_WINDOW = {
src/proxy_lite/environments/webbrowser.py CHANGED
@@ -1,6 +1,6 @@
1
  import base64
2
  from functools import cached_property
3
- from typing import Any, Literal, Optional, Self
4
 
5
  from proxy_lite.browser.browser import BrowserSession
6
  from proxy_lite.environments.environment_base import (
@@ -12,8 +12,7 @@ from proxy_lite.environments.environment_base import (
12
  State,
13
  )
14
  from proxy_lite.tools import BrowserTool, Tool, ToolExecutionResponse
15
- # Import logger from proxy_lite.logger, or if it's already available via BaseEnvironment
16
- from proxy_lite.logger import logger # Assuming you want to use the same logger
17
 
18
  @Environments.register_environment_config("webbrowser")
19
  class WebBrowserEnvironmentConfig(BaseEnvironmentConfig):
@@ -30,6 +29,10 @@ class WebBrowserEnvironmentConfig(BaseEnvironmentConfig):
30
  headless: bool = True
31
  keep_original_image: bool = False
32
  no_pois_in_image: bool = False
 
 
 
 
33
 
34
 
35
  @Environments.register_environment("webbrowser")
@@ -50,8 +53,12 @@ class WebBrowserEnvironment(BaseEnvironment):
50
  )
51
  await self.browser.__aenter__()
52
  # Initialize other resources if necessary
53
- if self.cookies:
54
- await self.browser.context.add_cookies(self.cookies)
 
 
 
 
55
  self.logger.info("🌐 [bold blue]Browser session started.[/]")
56
  return self
57
 
@@ -71,10 +78,14 @@ class WebBrowserEnvironment(BaseEnvironment):
71
  def browser_session(self) -> type[BrowserSession]:
72
  return BrowserSession
73
 
 
 
 
74
  @property
75
  def cookies(self) -> list[dict]:
76
- return []
77
-
 
78
  async def initialise(self) -> Observation:
79
  self.logger.debug(f"DEBUG: Initialising WebBrowserEnvironment. Homepage: {self.config.homepage}")
80
  try:
 
1
  import base64
2
  from functools import cached_property
3
+ from typing import Any, Literal, Optional, Self, List # Added List import
4
 
5
  from proxy_lite.browser.browser import BrowserSession
6
  from proxy_lite.environments.environment_base import (
 
12
  State,
13
  )
14
  from proxy_lite.tools import BrowserTool, Tool, ToolExecutionResponse
15
+ from proxy_lite.logger import logger
 
16
 
17
  @Environments.register_environment_config("webbrowser")
18
  class WebBrowserEnvironmentConfig(BaseEnvironmentConfig):
 
29
  headless: bool = True
30
  keep_original_image: bool = False
31
  no_pois_in_image: bool = False
32
+ # --- MODIFICATION START ---
33
+ # Added to accept initial cookies from the RunnerConfig
34
+ initial_cookies: Optional[List[dict]] = None
35
+ # --- MODIFICATION END ---
36
 
37
 
38
  @Environments.register_environment("webbrowser")
 
53
  )
54
  await self.browser.__aenter__()
55
  # Initialize other resources if necessary
56
+ # --- MODIFICATION START ---
57
+ # Changed to use self.config.initial_cookies
58
+ if self.config.initial_cookies:
59
+ self.logger.info(f"🌐 [bold blue]Adding {len(self.config.initial_cookies)} initial cookies to browser context.[/]")
60
+ await self.browser.context.add_cookies(self.config.initial_cookies)
61
+ # --- MODIFICATION END ---
62
  self.logger.info("🌐 [bold blue]Browser session started.[/]")
63
  return self
64
 
 
78
  def browser_session(self) -> type[BrowserSession]:
79
  return BrowserSession
80
 
81
+ # --- MODIFICATION START ---
82
+ # Modified this property to return cookies from the config.
83
+ # It was previously hardcoded to return an empty list.
84
  @property
85
  def cookies(self) -> list[dict]:
86
+ return self.config.initial_cookies if self.config.initial_cookies is not None else []
87
+ # --- MODIFICATION END ---
88
+
89
  async def initialise(self) -> Observation:
90
  self.logger.debug(f"DEBUG: Initialising WebBrowserEnvironment. Homepage: {self.config.homepage}")
91
  try: