@@ -677,6 +677,12 @@ class PlannerExecutorConfig:
677677 planner_max_tokens : int = 2048
678678 planner_temperature : float = 0.0
679679
680+ # Page context for planning: when enabled, extracts page content as markdown
681+ # during initial planning to help the planner understand page type and structure.
682+ # This adds token cost but improves plan quality for complex pages.
683+ use_page_context : bool = False
684+ page_context_max_chars : int = 8000 # Max chars of markdown to include
685+
680686 # Executor LLM settings
681687 executor_max_tokens : int = 96
682688 executor_temperature : float = 0.0
@@ -1228,10 +1234,20 @@ def build_planner_prompt(
12281234 auth_state : str = "unknown" ,
12291235 strict : bool = False ,
12301236 schema_errors : str | None = None ,
1237+ page_context : str | None = None ,
12311238) -> tuple [str , str ]:
12321239 """
12331240 Build system and user prompts for the Planner LLM.
12341241
1242+ Args:
1243+ task: Task description
1244+ start_url: Starting URL
1245+ site_type: Type of site (general, e-commerce, etc.)
1246+ auth_state: Authentication state
1247+ strict: If True, emphasize JSON-only output
1248+ schema_errors: Errors from previous parsing attempt
1249+ page_context: Optional markdown content of the current page for context
1250+
12351251 Returns:
12361252 (system_prompt, user_prompt)
12371253 """
@@ -1330,12 +1346,27 @@ def build_planner_prompt(
13301346{ domain_guidance }
13311347Return ONLY valid JSON. No prose, no code fences, no markdown."""
13321348
1349+ # Build page context section if provided
1350+ page_context_section = ""
1351+ if page_context :
1352+ page_context_section = f"""
1353+
1354+ Current Page Content:
1355+ The following is a markdown representation of the current page content. Use this to understand
1356+ the page structure, available elements (buttons, links, forms), and content to inform your plan.
1357+ Note: This may be truncated if the page is large.
1358+
1359+ ---
1360+ { page_context }
1361+ ---
1362+ """
1363+
13331364 user = f"""Task: { task }
13341365{ schema_note }
13351366Starting URL: { start_url or "browser's current page" }
13361367Site type: { site_type }
13371368Auth state: { auth_state }
1338-
1369+ { page_context_section }
13391370Output a JSON plan to accomplish this task. Each step should represent ONE distinct action."""
13401371
13411372 return system , user
@@ -2506,6 +2537,7 @@ async def plan(
25062537 * ,
25072538 start_url : str | None = None ,
25082539 max_attempts : int = 2 ,
2540+ page_context : str | None = None ,
25092541 ) -> Plan :
25102542 """
25112543 Generate execution plan for the given task.
@@ -2514,6 +2546,7 @@ async def plan(
25142546 task: Task description
25152547 start_url: Starting URL
25162548 max_attempts: Maximum planning attempts
2549+ page_context: Optional markdown content of current page for better planning
25172550
25182551 Returns:
25192552 Plan object with steps
@@ -2529,6 +2562,7 @@ async def plan(
25292562 start_url = start_url ,
25302563 strict = (attempt > 1 ),
25312564 schema_errors = last_errors or None ,
2565+ page_context = page_context if attempt == 1 else None , # Only include on first attempt
25322566 )
25332567
25342568 if self .config .verbose :
@@ -4557,9 +4591,21 @@ async def run(
45574591 step_outcomes : list [StepOutcome ] = []
45584592 error : str | None = None
45594593
4594+ # Optionally fetch page context (markdown) for better planning
4595+ page_context : str | None = None
4596+ if self .config .use_page_context :
4597+ try :
4598+ page_context = await runtime .read_markdown (
4599+ max_chars = self .config .page_context_max_chars
4600+ )
4601+ if self .config .verbose and page_context :
4602+ print (f" [PAGE-CONTEXT] Extracted { len (page_context )} chars of markdown for planning" , flush = True )
4603+ except Exception :
4604+ pass # Fail silently - page context is optional
4605+
45604606 try :
45614607 # Generate plan
4562- plan = await self .plan (task_description , start_url = start_url )
4608+ plan = await self .plan (task_description , start_url = start_url , page_context = page_context )
45634609
45644610 # Execute steps
45654611 step_index = 0
@@ -4764,7 +4810,18 @@ async def run(
47644810 continuation_task = self ._build_checkout_continuation_task (
47654811 task_description , page_type
47664812 )
4767- plan = await self .plan (continuation_task , start_url = None )
4813+ # Refresh page context for continuation planning if enabled
4814+ continuation_context : str | None = None
4815+ if self .config .use_page_context :
4816+ try :
4817+ continuation_context = await runtime .read_markdown (
4818+ max_chars = self .config .page_context_max_chars
4819+ )
4820+ except Exception :
4821+ pass
4822+ plan = await self .plan (
4823+ continuation_task , start_url = None , page_context = continuation_context
4824+ )
47684825 step_index = 0 # Start from beginning of new plan
47694826 self ._replans_used += 1
47704827 continue
0 commit comments