sera-browser 3.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. sera_browser-3.1.1/PKG-INFO +244 -0
  2. sera_browser-3.1.1/README.md +189 -0
  3. sera_browser-3.1.1/pyproject.toml +123 -0
  4. sera_browser-3.1.1/setup.cfg +4 -0
  5. sera_browser-3.1.1/src/sera_browser/__init__.py +203 -0
  6. sera_browser-3.1.1/src/sera_browser/__main__.py +26 -0
  7. sera_browser-3.1.1/src/sera_browser/api/__init__.py +6 -0
  8. sera_browser-3.1.1/src/sera_browser/api/app.py +275 -0
  9. sera_browser-3.1.1/src/sera_browser/browser/__init__.py +19 -0
  10. sera_browser-3.1.1/src/sera_browser/browser/browser_use_fallback.py +108 -0
  11. sera_browser-3.1.1/src/sera_browser/browser/cdp_ax.py +230 -0
  12. sera_browser-3.1.1/src/sera_browser/browser/context.py +163 -0
  13. sera_browser-3.1.1/src/sera_browser/browser/driver.py +801 -0
  14. sera_browser-3.1.1/src/sera_browser/browser/inspector.py +208 -0
  15. sera_browser-3.1.1/src/sera_browser/browser/manager.py +178 -0
  16. sera_browser-3.1.1/src/sera_browser/browser/refmap.py +283 -0
  17. sera_browser-3.1.1/src/sera_browser/browser/resolver.py +231 -0
  18. sera_browser-3.1.1/src/sera_browser/browser/screenshots.py +59 -0
  19. sera_browser-3.1.1/src/sera_browser/browser/som.py +216 -0
  20. sera_browser-3.1.1/src/sera_browser/browser/stealth.py +271 -0
  21. sera_browser-3.1.1/src/sera_browser/browser/storage.py +78 -0
  22. sera_browser-3.1.1/src/sera_browser/browser/tabs.py +260 -0
  23. sera_browser-3.1.1/src/sera_browser/browser/trimmer.py +141 -0
  24. sera_browser-3.1.1/src/sera_browser/browser/viewer.py +328 -0
  25. sera_browser-3.1.1/src/sera_browser/cancel.py +107 -0
  26. sera_browser-3.1.1/src/sera_browser/challenge/__init__.py +6 -0
  27. sera_browser-3.1.1/src/sera_browser/challenge/detector.py +301 -0
  28. sera_browser-3.1.1/src/sera_browser/config.py +209 -0
  29. sera_browser-3.1.1/src/sera_browser/eval/__init__.py +20 -0
  30. sera_browser-3.1.1/src/sera_browser/eval/harness.py +405 -0
  31. sera_browser-3.1.1/src/sera_browser/logging.py +128 -0
  32. sera_browser-3.1.1/src/sera_browser/models.py +340 -0
  33. sera_browser-3.1.1/src/sera_browser/net/__init__.py +6 -0
  34. sera_browser-3.1.1/src/sera_browser/net/recorder.py +288 -0
  35. sera_browser-3.1.1/src/sera_browser/security.py +137 -0
  36. sera_browser-3.1.1/src/sera_browser/session/__init__.py +6 -0
  37. sera_browser-3.1.1/src/sera_browser/session/manager.py +214 -0
  38. sera_browser-3.1.1/src/sera_browser/state/__init__.py +6 -0
  39. sera_browser-3.1.1/src/sera_browser/state/state.py +109 -0
  40. sera_browser-3.1.1/src/sera_browser/task/__init__.py +63 -0
  41. sera_browser-3.1.1/src/sera_browser/task/action_schema.py +412 -0
  42. sera_browser-3.1.1/src/sera_browser/task/agent.py +750 -0
  43. sera_browser-3.1.1/src/sera_browser/task/executor.py +532 -0
  44. sera_browser-3.1.1/src/sera_browser/task/extraction.py +169 -0
  45. sera_browser-3.1.1/src/sera_browser/task/history.py +190 -0
  46. sera_browser-3.1.1/src/sera_browser/task/llm_client.py +743 -0
  47. sera_browser-3.1.1/src/sera_browser/task/llm_planner.py +696 -0
  48. sera_browser-3.1.1/src/sera_browser/task/loop.py +102 -0
  49. sera_browser-3.1.1/src/sera_browser/task/memory.py +168 -0
  50. sera_browser-3.1.1/src/sera_browser/task/observability.py +246 -0
  51. sera_browser-3.1.1/src/sera_browser/task/pav.py +453 -0
  52. sera_browser-3.1.1/src/sera_browser/task/planner.py +192 -0
  53. sera_browser-3.1.1/src/sera_browser/task/report.py +139 -0
  54. sera_browser-3.1.1/src/sera_browser/task/safety.py +294 -0
  55. sera_browser-3.1.1/src/sera_browser/task/soft_restrict.py +92 -0
  56. sera_browser-3.1.1/src/sera_browser.egg-info/PKG-INFO +244 -0
  57. sera_browser-3.1.1/src/sera_browser.egg-info/SOURCES.txt +78 -0
  58. sera_browser-3.1.1/src/sera_browser.egg-info/dependency_links.txt +1 -0
  59. sera_browser-3.1.1/src/sera_browser.egg-info/entry_points.txt +2 -0
  60. sera_browser-3.1.1/src/sera_browser.egg-info/requires.txt +32 -0
  61. sera_browser-3.1.1/src/sera_browser.egg-info/top_level.txt +1 -0
  62. sera_browser-3.1.1/tests/test_advanced_features.py +659 -0
  63. sera_browser-3.1.1/tests/test_api.py +121 -0
  64. sera_browser-3.1.1/tests/test_cancellation.py +99 -0
  65. sera_browser-3.1.1/tests/test_challenge.py +77 -0
  66. sera_browser-3.1.1/tests/test_dsh_features.py +498 -0
  67. sera_browser-3.1.1/tests/test_followups.py +569 -0
  68. sera_browser-3.1.1/tests/test_juice_shop.py +123 -0
  69. sera_browser-3.1.1/tests/test_llm_integration.py +180 -0
  70. sera_browser-3.1.1/tests/test_llm_planner.py +603 -0
  71. sera_browser-3.1.1/tests/test_llm_provider_agnostic.py +825 -0
  72. sera_browser-3.1.1/tests/test_loop_detection.py +54 -0
  73. sera_browser-3.1.1/tests/test_navigation.py +95 -0
  74. sera_browser-3.1.1/tests/test_network.py +128 -0
  75. sera_browser-3.1.1/tests/test_screenshots.py +71 -0
  76. sera_browser-3.1.1/tests/test_session_isolation.py +100 -0
  77. sera_browser-3.1.1/tests/test_state.py +104 -0
  78. sera_browser-3.1.1/tests/test_tier2_features.py +337 -0
  79. sera_browser-3.1.1/tests/test_timeout_crash.py +65 -0
  80. sera_browser-3.1.1/tests/test_viewer.py +354 -0
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: sera-browser
3
+ Version: 3.1.1
4
+ Summary: Standalone Playwright-first autonomous browser agent for SERA — provider-agnostic LLM planner, real-view human-takeoverable browser, CDP AX tree, multi-tab, stealth, history/replay, structured extraction.
5
+ Author-email: mir-ashiq <imsrenpsycho@gmail.com>
6
+ Maintainer-email: mir-ashiq <imsrenpsycho@gmail.com>
7
+ License: Apache-2.0
8
+ Project-URL: Homepage, https://github.com/mir-ashiq/sera-browser
9
+ Project-URL: Repository, https://github.com/mir-ashiq/sera-browser
10
+ Project-URL: Issues, https://github.com/mir-ashiq/sera-browser/issues
11
+ Project-URL: Documentation, https://github.com/mir-ashiq/sera-browser/tree/main/docs
12
+ Keywords: playwright,browser-automation,agent,sera,security,llm,cdp,accessibility,autonomous
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
22
+ Classifier: Topic :: Software Development :: Testing
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.12
26
+ Description-Content-Type: text/markdown
27
+ Requires-Dist: playwright>=1.57
28
+ Requires-Dist: fastapi>=0.110
29
+ Requires-Dist: uvicorn[standard]>=0.29
30
+ Requires-Dist: pydantic>=2.6
31
+ Requires-Dist: pydantic-settings>=2.2
32
+ Requires-Dist: httpx>=0.27
33
+ Requires-Dist: anyio>=4.3
34
+ Requires-Dist: tenacity>=8.2
35
+ Provides-Extra: fallback
36
+ Requires-Dist: browser-use>=0.1.30; extra == "fallback"
37
+ Provides-Extra: vision
38
+ Requires-Dist: Pillow>=10.0; extra == "vision"
39
+ Provides-Extra: dev
40
+ Requires-Dist: pytest>=8; extra == "dev"
41
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
42
+ Requires-Dist: pytest-timeout>=2.3; extra == "dev"
43
+ Requires-Dist: pytest-cov>=4; extra == "dev"
44
+ Requires-Dist: httpx>=0.27; extra == "dev"
45
+ Requires-Dist: trio>=0.25; extra == "dev"
46
+ Requires-Dist: build>=1.0; extra == "dev"
47
+ Requires-Dist: twine>=4.0; extra == "dev"
48
+ Provides-Extra: test
49
+ Requires-Dist: pytest>=8; extra == "test"
50
+ Requires-Dist: pytest-asyncio>=0.23; extra == "test"
51
+ Requires-Dist: pytest-timeout>=2.3; extra == "test"
52
+ Requires-Dist: pytest-cov>=4; extra == "test"
53
+ Requires-Dist: httpx>=0.27; extra == "test"
54
+ Requires-Dist: trio>=0.25; extra == "test"
55
+
56
+ # SERA Browser Agent
57
+
58
+ A standalone, production-quality **Playwright-first** autonomous browser agent.
59
+ Receives a high-level objective, drives a real browser, reasons from a single
60
+ structured browser state, escalates to vision only when needed, and returns a
61
+ deterministic structured report.
62
+
63
+ Designed as a reusable worker that SERA can call without any Playwright
64
+ knowledge. Now supports a **real-view, human-takeoverable browser** for the
65
+ SERA assessment chat UI.
66
+
67
+ > Status: standalone. The SERA integration itself is **not** implemented in
68
+ > this repository — only the contract (see `docs/ARCHITECTURE.md` §17).
69
+
70
+ ## Highlights
71
+
72
+ - **Playwright first.** Direct async Playwright is the normal path.
73
+ Accessibility-tree/snapshot-driven interaction with deterministic element
74
+ refs (Playwright-MCP-inspired). No MCP runtime dependency.
75
+ - **Reason-from-state.** One structured `BrowserState` per task; no
76
+ re-scraping on every step.
77
+ - **LLM planner with provider-agnostic layer + deterministic fallback.**
78
+ Optional LLM-backed planner (`SBA_LLM_PROVIDER`) receives a structured
79
+ state view, returns a validated action from a fixed set, and the
80
+ `ActionExecutor` executes it. The LLM never touches Playwright directly.
81
+ Supports Z.ai (`zai`), any OpenAI-compatible API (`openai` — OpenAI,
82
+ Azure, OpenRouter, Ollama, vLLM, ...), or `none` (deterministic only).
83
+ Falls back to the deterministic planner on unavailable / timeout / invalid
84
+ action / cancellation.
85
+ - **Vision is optional, not default.** Screenshots are only sent to the LLM
86
+ on the loop-recovery escalation path, never on every step.
87
+ - **Idempotent `navigate`.** If the URL is already current, the agent only
88
+ re-snapshots (no reload) unless reload is explicit.
89
+ - **Bounded everything.** Timeouts, cancellation, and bounded retries on every
90
+ operation.
91
+ - **Loop detection.** Tool repetition + semantic (dom_hash) repetition, with
92
+ recovery or declared block.
93
+ - **Network intelligence.** Structured request/response/WebSocket recording
94
+ with sensitive-header redaction. Reusable as a security sensor for SERA.
95
+ - **Challenge-aware.** Detects CAPTCHA / Turnstile / Cloudflare / hCaptcha /
96
+ reCAPTCHA / MFA. Uses official test keys on owned test sites; pauses for
97
+ human-in-the-loop otherwise. **Never bypasses** third-party protections.
98
+ - **Optional `browser-use` fallback.** Lazy-imported, off by default, never
99
+ the normal path, shares the same state/session/cancellation/result format.
100
+ - **Browser isolation.** Per-task isolated context. `cancel_task` +
101
+ `force_cleanup` guarantee no leaked Chromium / context / page / WebSocket.
102
+ - **Security boundaries.** SSRF on by default; explicit `local_lab` +
103
+ allowlist for private targets; no credential logging; selectors validated
104
+ against the snapshot.
105
+ - **Real-view browser (human-takeoverable).** When `SBA_ENABLE_VIEWER=true`,
106
+ the browser launches in headed mode with CDP remote debugging. The SERA
107
+ chat UI connects via WebSocket to watch every step in real-time
108
+ (screenshots + state). The human can grab control at any time via
109
+ `POST /tasks/{id}/human_takeover` — the agent pauses, the human interacts,
110
+ then `POST /tasks/{id}/resume` continues.
111
+
112
+ ## Quick start
113
+
114
+ ```bash
115
+ pip install sera-browser
116
+ playwright install chromium
117
+ sera-browser # API on 127.0.0.1:8765
118
+ ```
119
+
120
+ Or for development:
121
+
122
+ ```bash
123
+ git clone https://github.com/mir-ashiq/sera-browser.git
124
+ cd sera-browser
125
+ pip install -e ".[dev]"
126
+ playwright install chromium
127
+ python -m sera_browser # API on 127.0.0.1:8765
128
+ ```
129
+
130
+ Create a task:
131
+
132
+ ```bash
133
+ curl -X POST http://127.0.0.1:8765/tasks \
134
+ -H 'content-type: application/json' \
135
+ -d '{
136
+ "target": "http://localhost:3000",
137
+ "task": "Analyze this application for business flows, authentication, APIs, routes, technologies and security-relevant browser behavior.",
138
+ "browser_mode": "headless",
139
+ "timeout": 180,
140
+ "local_lab": true,
141
+ "allowed_targets": ["localhost:3000", "127.0.0.1:3000"]
142
+ }'
143
+ ```
144
+
145
+ ## Real-View Browser (Human-Takeoverable, for SERA Chat UI)
146
+
147
+ The "real view, not a relay" paradigm: the browser is a **native visible
148
+ window** the human can see and interact with, not a headless relay. The agent
149
+ streams every step to the SERA chat UI in real-time, and the human can grab
150
+ control at any time.
151
+
152
+ ### Enable
153
+
154
+ ```bash
155
+ SBA_ENABLE_VIEWER=true
156
+ SBA_VIEWER_CDP_PORT=9222
157
+ # The browser will launch in headed mode with CDP remote debugging.
158
+ ```
159
+
160
+ ### How it works
161
+
162
+ 1. **CDP remote debugging** — Chromium launches with `--remote-debugging-port=9222`.
163
+ The SERA UI (or `chrome://inspect`) can connect to the same browser instance
164
+ for full interactive access.
165
+
166
+ 2. **Screenshot + state streaming** — after each agent step, a JPEG screenshot +
167
+ current URL/title/step info is streamed to connected WebSocket clients.
168
+ The SERA chat UI renders this stream for real-time visibility.
169
+
170
+ 3. **Human takeover** — the agent (or the human via API) can trigger a takeover.
171
+ The agent pauses, the human interacts with the real browser window, then
172
+ signals "done". The agent re-observes and continues.
173
+
174
+ ### API endpoints
175
+
176
+ | Method | Path | Purpose |
177
+ |---|---|---|
178
+ | GET | `/tasks/{id}/viewer` | Viewer status (CDP URL, takeover state, stats) |
179
+ | POST | `/tasks/{id}/human_takeover` | Pause agent for human interaction |
180
+ | POST | `/tasks/{id}/resume` | Resume agent after human takeover |
181
+ | GET | `/tasks/{id}/screenshot` | Current page screenshot (base64 data URL) |
182
+ | WS | `/tasks/{id}/stream` | Real-time browser state stream |
183
+
184
+ ### SERA chat UI integration
185
+
186
+ ```javascript
187
+ // Connect to the real-time stream
188
+ const ws = new WebSocket(`ws://localhost:8765/tasks/${taskId}/stream`);
189
+ ws.onmessage = (event) => {
190
+ const data = JSON.parse(event.data);
191
+ if (data.type === "step") {
192
+ // data.data.screenshot is a base64 JPEG data URL
193
+ document.getElementById("browser-view").src = data.data.screenshot;
194
+ document.getElementById("step-info").textContent =
195
+ `Step ${data.data.step}: ${data.data.action} → ${data.data.url}`;
196
+ }
197
+ if (data.type === "takeover") {
198
+ // Show "Agent paused — human can interact" banner
199
+ }
200
+ if (data.type === "resume") {
201
+ // Hide the banner
202
+ }
203
+ };
204
+
205
+ // Request human takeover
206
+ fetch(`http://localhost:8765/tasks/${taskId}/human_takeover`, { method: "POST" });
207
+
208
+ // Resume after the human is done
209
+ fetch(`http://localhost:8765/tasks/${taskId}/resume`, { method: "POST" });
210
+ ```
211
+
212
+ ### CDP direct access
213
+
214
+ The SERA UI can also connect directly to the browser via CDP for full
215
+ interactive control (DevTools, custom inspector, etc.):
216
+
217
+ ```
218
+ http://127.0.0.1:9222 (the CDP endpoint — exposed in /tasks/{id}/viewer)
219
+ ```
220
+
221
+ ## Documentation
222
+
223
+ - `docs/ARCHITECTURE.md` — component map, flow, integration contract.
224
+ - `docs/BROWSER-AUTOMATION.md` — operational manual, primitives, challenges.
225
+ - `docs/DECISIONS.md` — ADR log.
226
+ - `docs/RELEASE.md` — release process, PyPI Trusted Publishing, versioning.
227
+ - `docs/SERA-INTEGRATION.md` — SERA integration contract (library + HTTP modes).
228
+
229
+ ## Installation
230
+
231
+ ```bash
232
+ # From PyPI (public):
233
+ pip install sera-browser
234
+
235
+ # With optional extras:
236
+ pip install "sera-browser[fallback,vision,dev]"
237
+ ```
238
+
239
+ The package is **public on PyPI**; the source repository is **private on GitHub**.
240
+ PyPI publishing uses Trusted Publishing (OIDC, no stored tokens).
241
+
242
+ ## License
243
+
244
+ Apache-2.0.
@@ -0,0 +1,189 @@
1
+ # SERA Browser Agent
2
+
3
+ A standalone, production-quality **Playwright-first** autonomous browser agent.
4
+ Receives a high-level objective, drives a real browser, reasons from a single
5
+ structured browser state, escalates to vision only when needed, and returns a
6
+ deterministic structured report.
7
+
8
+ Designed as a reusable worker that SERA can call without any Playwright
9
+ knowledge. Now supports a **real-view, human-takeoverable browser** for the
10
+ SERA assessment chat UI.
11
+
12
+ > Status: standalone. The SERA integration itself is **not** implemented in
13
+ > this repository — only the contract (see `docs/ARCHITECTURE.md` §17).
14
+
15
+ ## Highlights
16
+
17
+ - **Playwright first.** Direct async Playwright is the normal path.
18
+ Accessibility-tree/snapshot-driven interaction with deterministic element
19
+ refs (Playwright-MCP-inspired). No MCP runtime dependency.
20
+ - **Reason-from-state.** One structured `BrowserState` per task; no
21
+ re-scraping on every step.
22
+ - **LLM planner with provider-agnostic layer + deterministic fallback.**
23
+ Optional LLM-backed planner (`SBA_LLM_PROVIDER`) receives a structured
24
+ state view, returns a validated action from a fixed set, and the
25
+ `ActionExecutor` executes it. The LLM never touches Playwright directly.
26
+ Supports Z.ai (`zai`), any OpenAI-compatible API (`openai` — OpenAI,
27
+ Azure, OpenRouter, Ollama, vLLM, ...), or `none` (deterministic only).
28
+ Falls back to the deterministic planner on unavailable / timeout / invalid
29
+ action / cancellation.
30
+ - **Vision is optional, not default.** Screenshots are only sent to the LLM
31
+ on the loop-recovery escalation path, never on every step.
32
+ - **Idempotent `navigate`.** If the URL is already current, the agent only
33
+ re-snapshots (no reload) unless reload is explicit.
34
+ - **Bounded everything.** Timeouts, cancellation, and bounded retries on every
35
+ operation.
36
+ - **Loop detection.** Tool repetition + semantic (dom_hash) repetition, with
37
+ recovery or declared block.
38
+ - **Network intelligence.** Structured request/response/WebSocket recording
39
+ with sensitive-header redaction. Reusable as a security sensor for SERA.
40
+ - **Challenge-aware.** Detects CAPTCHA / Turnstile / Cloudflare / hCaptcha /
41
+ reCAPTCHA / MFA. Uses official test keys on owned test sites; pauses for
42
+ human-in-the-loop otherwise. **Never bypasses** third-party protections.
43
+ - **Optional `browser-use` fallback.** Lazy-imported, off by default, never
44
+ the normal path, shares the same state/session/cancellation/result format.
45
+ - **Browser isolation.** Per-task isolated context. `cancel_task` +
46
+ `force_cleanup` guarantee no leaked Chromium / context / page / WebSocket.
47
+ - **Security boundaries.** SSRF on by default; explicit `local_lab` +
48
+ allowlist for private targets; no credential logging; selectors validated
49
+ against the snapshot.
50
+ - **Real-view browser (human-takeoverable).** When `SBA_ENABLE_VIEWER=true`,
51
+ the browser launches in headed mode with CDP remote debugging. The SERA
52
+ chat UI connects via WebSocket to watch every step in real-time
53
+ (screenshots + state). The human can grab control at any time via
54
+ `POST /tasks/{id}/human_takeover` — the agent pauses, the human interacts,
55
+ then `POST /tasks/{id}/resume` continues.
56
+
57
+ ## Quick start
58
+
59
+ ```bash
60
+ pip install sera-browser
61
+ playwright install chromium
62
+ sera-browser # API on 127.0.0.1:8765
63
+ ```
64
+
65
+ Or for development:
66
+
67
+ ```bash
68
+ git clone https://github.com/mir-ashiq/sera-browser.git
69
+ cd sera-browser
70
+ pip install -e ".[dev]"
71
+ playwright install chromium
72
+ python -m sera_browser # API on 127.0.0.1:8765
73
+ ```
74
+
75
+ Create a task:
76
+
77
+ ```bash
78
+ curl -X POST http://127.0.0.1:8765/tasks \
79
+ -H 'content-type: application/json' \
80
+ -d '{
81
+ "target": "http://localhost:3000",
82
+ "task": "Analyze this application for business flows, authentication, APIs, routes, technologies and security-relevant browser behavior.",
83
+ "browser_mode": "headless",
84
+ "timeout": 180,
85
+ "local_lab": true,
86
+ "allowed_targets": ["localhost:3000", "127.0.0.1:3000"]
87
+ }'
88
+ ```
89
+
90
+ ## Real-View Browser (Human-Takeoverable, for SERA Chat UI)
91
+
92
+ The "real view, not a relay" paradigm: the browser is a **native visible
93
+ window** the human can see and interact with, not a headless relay. The agent
94
+ streams every step to the SERA chat UI in real-time, and the human can grab
95
+ control at any time.
96
+
97
+ ### Enable
98
+
99
+ ```bash
100
+ SBA_ENABLE_VIEWER=true
101
+ SBA_VIEWER_CDP_PORT=9222
102
+ # The browser will launch in headed mode with CDP remote debugging.
103
+ ```
104
+
105
+ ### How it works
106
+
107
+ 1. **CDP remote debugging** — Chromium launches with `--remote-debugging-port=9222`.
108
+ The SERA UI (or `chrome://inspect`) can connect to the same browser instance
109
+ for full interactive access.
110
+
111
+ 2. **Screenshot + state streaming** — after each agent step, a JPEG screenshot +
112
+ current URL/title/step info is streamed to connected WebSocket clients.
113
+ The SERA chat UI renders this stream for real-time visibility.
114
+
115
+ 3. **Human takeover** — the agent (or the human via API) can trigger a takeover.
116
+ The agent pauses, the human interacts with the real browser window, then
117
+ signals "done". The agent re-observes and continues.
118
+
119
+ ### API endpoints
120
+
121
+ | Method | Path | Purpose |
122
+ |---|---|---|
123
+ | GET | `/tasks/{id}/viewer` | Viewer status (CDP URL, takeover state, stats) |
124
+ | POST | `/tasks/{id}/human_takeover` | Pause agent for human interaction |
125
+ | POST | `/tasks/{id}/resume` | Resume agent after human takeover |
126
+ | GET | `/tasks/{id}/screenshot` | Current page screenshot (base64 data URL) |
127
+ | WS | `/tasks/{id}/stream` | Real-time browser state stream |
128
+
129
+ ### SERA chat UI integration
130
+
131
+ ```javascript
132
+ // Connect to the real-time stream
133
+ const ws = new WebSocket(`ws://localhost:8765/tasks/${taskId}/stream`);
134
+ ws.onmessage = (event) => {
135
+ const data = JSON.parse(event.data);
136
+ if (data.type === "step") {
137
+ // data.data.screenshot is a base64 JPEG data URL
138
+ document.getElementById("browser-view").src = data.data.screenshot;
139
+ document.getElementById("step-info").textContent =
140
+ `Step ${data.data.step}: ${data.data.action} → ${data.data.url}`;
141
+ }
142
+ if (data.type === "takeover") {
143
+ // Show "Agent paused — human can interact" banner
144
+ }
145
+ if (data.type === "resume") {
146
+ // Hide the banner
147
+ }
148
+ };
149
+
150
+ // Request human takeover
151
+ fetch(`http://localhost:8765/tasks/${taskId}/human_takeover`, { method: "POST" });
152
+
153
+ // Resume after the human is done
154
+ fetch(`http://localhost:8765/tasks/${taskId}/resume`, { method: "POST" });
155
+ ```
156
+
157
+ ### CDP direct access
158
+
159
+ The SERA UI can also connect directly to the browser via CDP for full
160
+ interactive control (DevTools, custom inspector, etc.):
161
+
162
+ ```
163
+ http://127.0.0.1:9222 (the CDP endpoint — exposed in /tasks/{id}/viewer)
164
+ ```
165
+
166
+ ## Documentation
167
+
168
+ - `docs/ARCHITECTURE.md` — component map, flow, integration contract.
169
+ - `docs/BROWSER-AUTOMATION.md` — operational manual, primitives, challenges.
170
+ - `docs/DECISIONS.md` — ADR log.
171
+ - `docs/RELEASE.md` — release process, PyPI Trusted Publishing, versioning.
172
+ - `docs/SERA-INTEGRATION.md` — SERA integration contract (library + HTTP modes).
173
+
174
+ ## Installation
175
+
176
+ ```bash
177
+ # From PyPI (public):
178
+ pip install sera-browser
179
+
180
+ # With optional extras:
181
+ pip install "sera-browser[fallback,vision,dev]"
182
+ ```
183
+
184
+ The package is **public on PyPI**; the source repository is **private on GitHub**.
185
+ PyPI publishing uses Trusted Publishing (OIDC, no stored tokens).
186
+
187
+ ## License
188
+
189
+ Apache-2.0.
@@ -0,0 +1,123 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sera-browser"
7
+ version = "3.1.1"
8
+ description = "Standalone Playwright-first autonomous browser agent for SERA — provider-agnostic LLM planner, real-view human-takeoverable browser, CDP AX tree, multi-tab, stealth, history/replay, structured extraction."
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ license = { text = "Apache-2.0" }
12
+ authors = [
13
+ { name = "mir-ashiq", email = "imsrenpsycho@gmail.com" }
14
+ ]
15
+ maintainers = [
16
+ { name = "mir-ashiq", email = "imsrenpsycho@gmail.com" }
17
+ ]
18
+ keywords = [
19
+ "playwright",
20
+ "browser-automation",
21
+ "agent",
22
+ "sera",
23
+ "security",
24
+ "llm",
25
+ "cdp",
26
+ "accessibility",
27
+ "autonomous",
28
+ ]
29
+ classifiers = [
30
+ "Development Status :: 4 - Beta",
31
+ "Intended Audience :: Developers",
32
+ "License :: OSI Approved :: Apache Software License",
33
+ "Operating System :: POSIX :: Linux",
34
+ "Operating System :: MacOS",
35
+ "Programming Language :: Python :: 3",
36
+ "Programming Language :: Python :: 3.12",
37
+ "Programming Language :: Python :: 3.13",
38
+ "Topic :: Internet :: WWW/HTTP :: Browsers",
39
+ "Topic :: Software Development :: Testing",
40
+ "Topic :: Software Development :: Libraries :: Python Modules",
41
+ "Typing :: Typed",
42
+ ]
43
+ dependencies = [
44
+ "playwright>=1.57",
45
+ "fastapi>=0.110",
46
+ "uvicorn[standard]>=0.29",
47
+ "pydantic>=2.6",
48
+ "pydantic-settings>=2.2",
49
+ "httpx>=0.27",
50
+ "anyio>=4.3",
51
+ "tenacity>=8.2",
52
+ ]
53
+
54
+ [project.optional-dependencies]
55
+ # Optional: browser-use fallback driver for difficult visual interactions.
56
+ fallback = [
57
+ "browser-use>=0.1.30",
58
+ ]
59
+ # Optional: vision escalation (Set-of-Mark screenshot annotation).
60
+ vision = [
61
+ "Pillow>=10.0",
62
+ ]
63
+ # Development + testing dependencies.
64
+ dev = [
65
+ "pytest>=8",
66
+ "pytest-asyncio>=0.23",
67
+ "pytest-timeout>=2.3",
68
+ "pytest-cov>=4",
69
+ "httpx>=0.27",
70
+ "trio>=0.25",
71
+ "build>=1.0",
72
+ "twine>=4.0",
73
+ ]
74
+ # Alias for backward compatibility.
75
+ test = [
76
+ "pytest>=8",
77
+ "pytest-asyncio>=0.23",
78
+ "pytest-timeout>=2.3",
79
+ "pytest-cov>=4",
80
+ "httpx>=0.27",
81
+ "trio>=0.25",
82
+ ]
83
+
84
+ [project.scripts]
85
+ sera-browser = "sera_browser_agent.__main__:main"
86
+
87
+ [project.urls]
88
+ Homepage = "https://github.com/mir-ashiq/sera-browser"
89
+ Repository = "https://github.com/mir-ashiq/sera-browser"
90
+ Issues = "https://github.com/mir-ashiq/sera-browser/issues"
91
+ Documentation = "https://github.com/mir-ashiq/sera-browser/tree/main/docs"
92
+
93
+ [tool.setuptools.packages.find]
94
+ where = ["src"]
95
+
96
+ [tool.setuptools.package-data]
97
+ sera_browser_agent = ["py.typed"]
98
+
99
+ [tool.pytest.ini_options]
100
+ asyncio_mode = "auto"
101
+ testpaths = ["tests"]
102
+ markers = [
103
+ "juice_shop: tests requiring OWASP Juice Shop to be running",
104
+ "slow: tests that take more than 10 seconds",
105
+ ]
106
+ addopts = "-ra --strict-markers"
107
+ filterwarnings = [
108
+ "error::DeprecationWarning:playwright.*",
109
+ ]
110
+
111
+ [tool.coverage.run]
112
+ source = ["sera_browser_agent"]
113
+ branch = true
114
+
115
+ [tool.coverage.report]
116
+ exclude_lines = [
117
+ "pragma: no cover",
118
+ "def __repr__",
119
+ "raise NotImplementedError",
120
+ "if __name__ == .__main__.:",
121
+ "pass",
122
+ "if TYPE_CHECKING:",
123
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+