You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(readme): normalize structure to AIWG gold-standard template
Restructure README to match AIWG's section ordering: centered header
with badges and nav, What Is, Why This Matters (Developers/Agents/
Operators), Core Capabilities, Quick Start, Session Persistence, Daemon
Mode, Screen Inspection, Bot Detection Flags, Binary Search Order,
Error Handling (table format), Documentation, Contributing, Community,
License, Sponsors (3-column table), Acknowledgments, Back to Top.
Content unchanged in substance — same API examples, same bot-detection
rationale. Rearranged and expanded for consistency with the carbonyl
and carbonyl-fleet readmes.
`carbonyl-agent` is the Python automation SDK for [Carbonyl](https://git.integrolabs.net/roctinam/carbonyl) — a Chromium-based headless browser that renders into terminal text. The SDK spawns Carbonyl via PTY, parses the screen via `pyte`, and exposes a high-level API for navigation, clicking, text extraction, and session persistence. It is designed for agent-driven web interaction: scripted scraping, automated form submission, and LLM-driven browsing loops that need a real browser but not a real display.
33
+
34
+
Unlike Playwright or Selenium, carbonyl-agent returns **terminal text**, not a DOM. This makes it fast (no screenshot decode), cheap (no GPU, no window server), and well-suited for the context windows of LLM-driven agents.
35
+
36
+
---
37
+
38
+
## Why This Matters
39
+
40
+
### For Developers
41
+
42
+
**A real browser, cheap and scriptable.** Most automation stacks require either a full display server (Selenium + Xvfb) or a heavyweight DevTools protocol (Playwright CDP). carbonyl-agent gives you Chromium rendering through a PTY — `pip install`, call `open()`, read `page_text()`. Named sessions persist cookies across runs; daemon mode keeps a browser warm across short-lived scripts.
43
+
44
+
### For Agents
45
+
46
+
**Rendered text is the native LLM format.** An LLM consuming `page_text()` gets the page as a human would read it in a terminal — headings, lists, table rows — without DOM noise or screenshot OCR. Built-in bot-detection evasion (Firefox UA, `AutomationControlled` suppression, HTTP/2 off) means agents aren't blocked by default on Akamai/Cloudflare-protected sites.
17
47
18
-
Python automation SDK for the [Carbonyl](https://git.integrolabs.net/roctinam/carbonyl) headless browser.
48
+
### For Operators
19
49
20
-
## Install
50
+
**Low footprint, no window server.** Runs in a safe-mode console, over SSH, or inside a container without X11/Wayland. Binary discovery is prioritized: env var → local install → PATH → Docker opt-in. Sessions and daemon sockets live under `~/.local/share/carbonyl/` with 0600/0700 permissions.
sm.restore("base", "post-login") # replaces profile with snapshot
84
139
```
85
140
86
-
See `SessionManager` for the full API (list, destroy, exists, is_live, clean_stale_lock).
141
+
See `SessionManager` for the full API: `list`, `destroy`, `exists`, `is_live`, `clean_stale_lock`.
142
+
143
+
---
87
144
88
145
## Daemon Mode
89
146
90
-
A long-running Carbonyl process exposed over a Unix socket. Clients reconnect without losing in-memory state:
147
+
A long-running Carbonyl process exposed over a Unix socket. Clients reconnect without losing in-memory state — ideal for agent loops that want to amortize browser startup cost across many short scripts.
91
148
92
149
```python
93
150
from carbonyl_agent import DaemonClient, start_daemon, stop_daemon
print(si.annotate(marks=[(m["col"], m["row"]) for m in matches]))
143
204
```
144
205
206
+
---
207
+
145
208
## Bot Detection Flags
146
209
147
210
`CarbonylBrowser` applies a curated `_HEADLESS_FLAGS` set at spawn time to minimize detection by commercial bot-detection engines (Akamai, Cloudflare, PerimeterX):
148
211
149
-
- Spoofed Firefox User-Agent (removes the "(Carbonyl)" marker and Chrome identifier)
212
+
- Spoofed Firefox User-Agent (removes the `(Carbonyl)` marker and Chrome identifier)
-`--disable-http2` (HTTP/2 SETTINGS frame is a fingerprint used server-side)
152
-
- Standard no-first-run, disable-sync, mock-keychain flags
214
+
-`--disable-http2` (HTTP/2 SETTINGS frame is a server-side fingerprint)
215
+
- Standard `--no-first-run`, `--disable-sync`, `--use-mock-keychain` flags
216
+
217
+
**If you hit bot-detection walls, do not remove these flags — they are the baseline.** For additional entropy, call `CarbonylBrowser.mouse_path([...])` to simulate organic mouse movement before interaction.
153
218
154
-
If you're hitting bot-detection walls, **do not remove these flags**. They are the baseline. For additional entropy, use `CarbonylBrowser.mouse_path([...])` to simulate organic mouse movement before interaction.
219
+
---
220
+
221
+
## Binary Search Order
222
+
223
+
1.`CARBONYL_BIN` env var (explicit path)
224
+
2.`~/.local/share/carbonyl/bin/<triple>/carbonyl` (installed by `carbonyl-agent install`)
Without `CARBONYL_ALLOW_DOCKER=1`, attempts to use Docker fallback raise `RuntimeError` with a clear message. The fallback pulls by pinned SHA256 digest, not a mutable `:latest` tag.
166
238
239
+
---
240
+
167
241
## Error Handling
168
242
169
243
Common exceptions:
170
244
171
-
-`ValueError` — invalid session name (path traversal, too long, empty)
172
-
-`FileExistsError` — session already exists on `create()`
173
-
-`KeyError` — session not found on `get()` / `destroy()` / `restore()`
174
-
-`RuntimeError` — session is live when a destructive op is requested (destroy/fork/restore); also when Docker fallback is blocked
175
-
-`pexpect.EOF` / `pexpect.TIMEOUT` — browser subprocess died or read timed out (handled internally by `drain()`; propagates on `send()`)
245
+
| Exception | Raised when |
246
+
|-----------|-------------|
247
+
|`ValueError`| invalid session name (path traversal, too long, empty) |
248
+
|`FileExistsError`| session already exists on `create()`|
249
+
|`KeyError`| session not found on `get()` / `destroy()` / `restore()`|
250
+
|`RuntimeError`| destructive op on a live session; Docker fallback blocked |
251
+
|`pexpect.EOF` / `pexpect.TIMEOUT`| browser subprocess died or read timed out |
176
252
177
253
Retry pattern for flaky network:
178
254
179
255
```python
256
+
import pexpect
257
+
from carbonyl_agent import CarbonylBrowser
258
+
259
+
b = CarbonylBrowser()
180
260
for attempt inrange(3):
181
261
try:
182
262
b.open(url)
@@ -187,13 +267,90 @@ for attempt in range(3):
187
267
b = CarbonylBrowser()
188
268
```
189
269
190
-
## Binary Search Order
270
+
---
191
271
192
-
1.`CARBONYL_BIN` env var (explicit path)
193
-
2.`~/.local/share/carbonyl/bin/<triple>/carbonyl` (installed by `carbonyl-agent install`)
-**[carbonyl](https://git.integrolabs.net/roctinam/carbonyl)** — the Chromium fork that produces the runtime binary
281
+
-**[carbonyl-fleet](https://git.integrolabs.net/roctinam/carbonyl-fleet)** — server for managing N concurrent Carbonyl instances over PTY + Unix socket
282
+
283
+
---
284
+
285
+
## Contributing
286
+
287
+
PRs and issues welcome at [git.integrolabs.net/roctinam/carbonyl-agent](https://git.integrolabs.net/roctinam/carbonyl-agent) or [github.com/jmagly/carbonyl-agent](https://github.com/jmagly/carbonyl-agent).
Enterprise-grade timing infrastructure for blockchain applications.
319
+
320
+
</td>
321
+
<tdwidth="33%"align="center">
322
+
323
+
### [Selfient](https://selfient.xyz)
324
+
325
+
**No-Code Smart Contracts for Everyone**
326
+
327
+
Making blockchain-based agreements accessible to all.
328
+
329
+
</td>
330
+
<tdwidth="33%"align="center">
331
+
332
+
### [Integro Labs](https://integrolabs.io)
333
+
334
+
**AI-Powered Automation Solutions**
335
+
336
+
Custom AI and blockchain solutions for the digital age.
337
+
338
+
</td>
339
+
</tr>
340
+
</table>
341
+
342
+
**Interested in sponsoring?** Open a discussion on [GitHub](https://github.com/jmagly/carbonyl-agent/discussions).
343
+
344
+
---
345
+
346
+
## Acknowledgments
347
+
348
+
Built on top of [Carbonyl](https://github.com/fathyb/carbonyl) by Fathy Boundjadj. The `roctinam/carbonyl` fork is actively maintained through the M147 Chromium line. PTY handling via [pexpect](https://github.com/pexpect/pexpect); terminal parsing via [pyte](https://github.com/selectel/pyte).
349
+
350
+
---
351
+
352
+
<divalign="center">
196
353
197
-
## Changelog
354
+
**[⬆ Back to Top](#carbonyl-agent)**
198
355
199
-
See [CHANGELOG.md](CHANGELOG.md) for release history.
0 commit comments