Skip to content

Commit f4eed7f

Browse files
guyernestclaude
andcommitted
feat(browser-agent): Add persistent browser session mode (v0.5.0)
Keep the browser alive between workflow runs to avoid repeated logins and bot detection. Adds server mode to Python executor (NDJSON over stdin/stdout), PersistentScriptExecutor in Rust, and a config toggle. - Python: --server-mode flag for persistent NDJSON protocol - Rust: PersistentScriptExecutor with start/execute/stop lifecycle - Rust: Tauri commands for persistent session management - Config: persistent_browser_session toggle in config.yaml and UI - Activity poller: auto-uses persistent executor when config enabled - Templates: navigate back to AddressHome after extraction - Examples: add 06_bt_broadband_template_test.json Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b6784ca commit f4eed7f

15 files changed

Lines changed: 1669 additions & 165 deletions

lambda/tools/local-browser-agent/examples/03_bt_broadband_bournemouth.json

Lines changed: 67 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"strategy": "selector",
6969
"value": "input[type='text'][name*='user'], input[type='email']"
7070
},
71-
"value": "{{username}}"
71+
"value": "nterizakis"
7272
}
7373
]
7474
},
@@ -81,7 +81,7 @@
8181
"strategy": "selector",
8282
"value": "input[type='text']:first-of-type"
8383
},
84-
"value": "{{username}}"
84+
"value": "nterizakis"
8585
}
8686
]
8787
}
@@ -455,10 +455,18 @@
455455
}
456456
]
457457
},
458+
{
459+
"action": "wait",
460+
"description": "Random delay before search to avoid bot detection",
461+
"duration_range": [
462+
1500,
463+
3500
464+
]
465+
},
458466
{
459467
"type": "try",
460468
"name": "ClickSearch",
461-
"description": "Click search button - includes retry for temporary 'service unavailable' errors",
469+
"description": "Click search button - includes retry for temporary 'checker is unavailable' errors",
462470
"strategies": [
463471
{
464472
"name": "Strategy 1: Submit button with retry",
@@ -471,10 +479,10 @@
471479
},
472480
"delay": 500,
473481
"retry": {
474-
"attempts": 3,
475-
"delay_ms": 1000,
482+
"attempts": 5,
483+
"delay_ms": 5000,
476484
"retry_if": {
477-
"text_visible": "service unavailable"
485+
"text_visible": "checker is unavailable"
478486
}
479487
}
480488
}
@@ -491,10 +499,10 @@
491499
},
492500
"delay": 500,
493501
"retry": {
494-
"attempts": 3,
495-
"delay_ms": 1000,
502+
"attempts": 5,
503+
"delay_ms": 5000,
496504
"retry_if": {
497-
"text_visible": "service unavailable"
505+
"text_visible": "checker is unavailable"
498506
}
499507
}
500508
}
@@ -505,6 +513,28 @@
505513
{
506514
"action": "wait_for_load_state",
507515
"state": "networkidle"
516+
},
517+
{
518+
"action": "wait",
519+
"description": "Wait for search results or error message to appear",
520+
"duration": 2000
521+
},
522+
{
523+
"type": "if",
524+
"name": "CheckSearchServiceAvailable",
525+
"description": "Detect if BT checker returned 'unavailable' error after search submit",
526+
"condition": {
527+
"type": "element_visible",
528+
"selector": "text=checker is unavailable",
529+
"timeout": 1000
530+
},
531+
"then": {
532+
"action": "error",
533+
"message": "BT Checker service unavailable - the checker returned: 'We are sorry but the checker is unavailable at the moment. Please try again later.'"
534+
},
535+
"else": {
536+
"continue": true
537+
}
508538
}
509539
],
510540
"next": "SelectAddress"
@@ -520,39 +550,39 @@
520550
"description": "Progressive address matching: regex -> fuzzy -> vision with scroll",
521551
"strategies": [
522552
{
523-
"name": "Strategy 1: Regex - building + first word only",
553+
"name": "Strategy 1: Regex - building (with range) + first word only",
524554
"steps": [
525555
{
526556
"action": "click",
527557
"locator": {
528558
"strategy": "selector",
529-
"value": "text=/^\\s*143\\s+\\w+/i",
559+
"value": "text=/^\\s*(?:\\d+-)?143(?:-\\d+)?[A-Za-z]?\\s+\\w+/i",
530560
"nth": 0
531561
}
532562
}
533563
]
534564
},
535565
{
536-
"name": "Strategy 2: Regex - building + street flexible",
566+
"name": "Strategy 2: Regex - building (with range) + street flexible",
537567
"steps": [
538568
{
539569
"action": "click",
540570
"locator": {
541571
"strategy": "selector",
542-
"value": "text=/143[\\s,]+Belle Vue Road/i",
572+
"value": "text=/(?:\\d+-)?143(?:-\\d+)?[A-Za-z]?[\\s,]+Belle Vue Road/i",
543573
"nth": 0
544574
}
545575
}
546576
]
547577
},
548578
{
549-
"name": "Strategy 3: Regex - street anywhere after building",
579+
"name": "Strategy 3: Regex - building (with range) + street anywhere",
550580
"steps": [
551581
{
552582
"action": "click",
553583
"locator": {
554584
"strategy": "selector",
555-
"value": "text=/143.*Belle Vue Road/i",
585+
"value": "text=/(?:\\d+-)?143(?:-\\d+)?[A-Za-z]?.*Belle Vue Road/i",
556586
"nth": 0
557587
}
558588
}
@@ -583,13 +613,16 @@
583613
},
584614
{
585615
"action": "wait",
586-
"description": "Wait before clicking submit to avoid bot detection",
587-
"duration": 500
616+
"description": "Random delay before submit to avoid bot detection",
617+
"duration_range": [
618+
1500,
619+
3500
620+
]
588621
},
589622
{
590623
"type": "try",
591624
"name": "ClickContinueAfterAddress",
592-
"description": "Click submit with retry for 'service unavailable' errors",
625+
"description": "Click submit with retry for 'checker is unavailable' errors",
593626
"strategies": [
594627
{
595628
"name": "Strategy 1: Submit button with retry",
@@ -603,9 +636,9 @@
603636
"delay": 300,
604637
"retry": {
605638
"attempts": 5,
606-
"delay_ms": 3000,
639+
"delay_ms": 5000,
607640
"retry_if": {
608-
"text_visible": "service unavailable"
641+
"text_visible": "checker is unavailable"
609642
}
610643
}
611644
}
@@ -623,9 +656,9 @@
623656
"delay": 300,
624657
"retry": {
625658
"attempts": 5,
626-
"delay_ms": 3000,
659+
"delay_ms": 5000,
627660
"retry_if": {
628-
"text_visible": "service unavailable"
661+
"text_visible": "checker is unavailable"
629662
}
630663
}
631664
}
@@ -661,7 +694,7 @@
661694
{
662695
"action": "wait_for_selector",
663696
"selector": ".ExhangeCodeSetup",
664-
"timeout": 15000
697+
"timeout": 30000
665698
}
666699
]
667700
},
@@ -679,7 +712,7 @@
679712
{
680713
"action": "wait_for_selector",
681714
"selector": "th:has-text('Featured Products')",
682-
"timeout": 20000
715+
"timeout": 30000
683716
}
684717
]
685718
},
@@ -768,9 +801,18 @@
768801
"fallback_js": "(() => { const rows = document.querySelectorAll('tr'); for (const r of rows) { const th = r.querySelector('th'); if (th && th.textContent.includes('Premise Type')) { const td = r.querySelector('td'); return td ? td.textContent.trim() : null; } } return null; })()"
769802
}
770803
]
804+
},
805+
{
806+
"action": "navigate",
807+
"url": "https://bbactotl.btwholesale.com/bbac-ui/totl/totlSearch/#/ADSL/AddressHome",
808+
"description": "Navigate back to search page for next run"
809+
},
810+
{
811+
"action": "wait_for_load_state",
812+
"state": "networkidle"
771813
}
772814
],
773815
"end": true
774816
}
775817
]
776-
}
818+
}

0 commit comments

Comments
 (0)