Skip to content

Commit 88b3ed5

Browse files
author
SentienceDEV
committed
updated readme with debugger
1 parent 7d7f658 commit 88b3ed5

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,64 @@ if __name__ == "__main__":
7878
asyncio.run(main())
7979
```
8080

81+
## SentienceDebugger: attach to your existing agent framework (sidecar mode)
82+
83+
If you already have an agent loop (LangGraph, browser-use, custom planner/executor), you can keep it and attach Sentience as a **verifier + trace layer**.
84+
85+
Key idea: your agent still decides and executes actions — Sentience **snapshots and verifies outcomes**.
86+
87+
```python
88+
from sentience import SentienceDebugger, create_tracer
89+
from sentience.verification import exists, url_contains
90+
91+
92+
async def run_existing_agent(page) -> None:
93+
# page: playwright.async_api.Page (owned by your agent/framework)
94+
tracer = create_tracer(run_id="run-123") # local JSONL by default
95+
dbg = SentienceDebugger.attach(page, tracer=tracer)
96+
97+
async with dbg.step("agent_step: navigate + verify"):
98+
# 1) Let your framework do whatever it does
99+
await your_agent.step()
100+
101+
# 2) Snapshot what the agent produced
102+
await dbg.snapshot()
103+
104+
# 3) Verify outcomes (with bounded retries)
105+
await dbg.check(url_contains("example.com"), label="on_domain", required=True).eventually(timeout_s=10)
106+
await dbg.check(exists("role=heading"), label="has_heading").eventually(timeout_s=10)
107+
```
108+
109+
## SDK-driven full loop (snapshots + actions)
110+
111+
If you want Sentience to drive the loop end-to-end, you can use the SDK primitives directly: take a snapshot, select elements, act, then verify.
112+
113+
```python
114+
from sentience import SentienceBrowser, snapshot, find, click, type_text, wait_for
115+
116+
117+
def login_example() -> None:
118+
with SentienceBrowser() as browser:
119+
browser.page.goto("https://example.com/login")
120+
121+
snap = snapshot(browser)
122+
email = find(snap, "role=textbox text~'email'")
123+
password = find(snap, "role=textbox text~'password'")
124+
submit = find(snap, "role=button text~'sign in'")
125+
126+
if not (email and password and submit):
127+
raise RuntimeError("login form not found")
128+
129+
type_text(browser, email.id, "user@example.com")
130+
type_text(browser, password.id, "password123")
131+
click(browser, submit.id)
132+
133+
# Verify success
134+
ok = wait_for(browser, "role=heading text~'Dashboard'", timeout=10.0)
135+
if not ok.found:
136+
raise RuntimeError("login failed")
137+
```
138+
81139
## Capabilities (lifecycle guarantees)
82140

83141
### Controlled perception

0 commit comments

Comments
 (0)