Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,34 @@ jobs:
run: |
echo "=== Installed sentience location ==="
python -c "import sentience; print(sentience.__file__)"
echo "=== Check assert_done source code ==="
echo "=== Check assert_done in installed package ==="
python -c "
import inspect
from sentience.agent_runtime import AgentRuntime
source = inspect.getsource(AgentRuntime.assert_done)
print(source[:500])
print(source)
if 'assertTrue' in source:
print('ERROR: assertTrue found in installed package!')
exit(1)
else:
print('Good: assert_ is correctly used')
"

- name: Verify source code
shell: bash
run: |
echo "=== Checking agent_runtime.py line 345 ==="
sed -n '340,350p' sentience/agent_runtime.py
echo "=== Verifying assert_ method exists ==="
grep -n "def assert_" sentience/agent_runtime.py
echo "=== Checking for assertTrue (should NOT exist) ==="
if grep -n "assertTrue" sentience/agent_runtime.py; then
echo "ERROR: Found assertTrue - this should have been removed!"
exit 1
else
echo "Good: no assertTrue found"
fi

- name: Lint with pre-commit
continue-on-error: true
run: |
Expand Down
4 changes: 2 additions & 2 deletions examples/agent_runtime_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
The AgentRuntime provides assertion predicates to verify browser state during execution.

Key features:
- BrowserBackendV0 protocol: Framework-agnostic browser integration
- BrowserBackend protocol: Framework-agnostic browser integration
- Predicate helpers: url_matches, url_contains, exists, not_exists, element_count
- Combinators: all_of, any_of for complex conditions
- Task completion: assert_done() for goal verification
Expand Down Expand Up @@ -44,7 +44,7 @@ async def main():
page = await browser.new_page()

# 3. Create AgentRuntime using from_sentience_browser factory
# This wraps the browser/page into the new BrowserBackendV0 architecture
# This wraps the browser/page into the new BrowserBackend architecture
runtime = await AgentRuntime.from_sentience_browser(
browser=browser,
page=page,
Expand Down
6 changes: 3 additions & 3 deletions examples/browser-use/agent_runtime_browser_use.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""
Example: Agent Runtime with browser-use Integration

Demonstrates how to use AgentRuntime with browser-use library via BrowserBackendV0 protocol.
Demonstrates how to use AgentRuntime with browser-use library via BrowserBackend protocol.
This pattern enables framework-agnostic browser integration for agent verification loops.

Key features:
- BrowserUseAdapter: Wraps browser-use BrowserSession into CDPBackendV0
- BrowserBackendV0 protocol: Minimal interface for browser operations
- BrowserBackend protocol: Minimal interface for browser operations
- Direct AgentRuntime construction: No need for from_sentience_browser factory

Requirements:
Expand Down Expand Up @@ -58,7 +58,7 @@ async def main():
await session.start()

try:
# 3. Create BrowserBackendV0 using BrowserUseAdapter
# 3. Create BrowserBackend using BrowserUseAdapter
# This wraps the browser-use session into the standard backend protocol
adapter = BrowserUseAdapter(session)
backend = await adapter.create_backend()
Expand Down
4 changes: 2 additions & 2 deletions sentience/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# Backend-agnostic actions (aliased to avoid conflict with existing actions)
# Browser backends (for browser-use integration)
from .backends import (
BrowserBackendV0,
BrowserBackend,
BrowserUseAdapter,
BrowserUseCDPTransport,
CachedSnapshot,
Expand Down Expand Up @@ -132,7 +132,7 @@
"verify_extension_version",
"verify_extension_version_async",
# Browser backends (for browser-use integration)
"BrowserBackendV0",
"BrowserBackend",
"CDPTransport",
"CDPBackendV0",
"PlaywrightBackend",
Expand Down
14 changes: 7 additions & 7 deletions sentience/agent_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Agent runtime for verification loop support.

This module provides a thin runtime wrapper that combines:
1. Browser session management (via BrowserBackendV0 protocol)
1. Browser session management (via BrowserBackend protocol)
2. Snapshot/query helpers
3. Tracer for event emission
4. Assertion/verification methods
Expand Down Expand Up @@ -72,7 +72,7 @@
if TYPE_CHECKING:
from playwright.async_api import Page

from .backends.protocol_v0 import BrowserBackendV0
from .backends.protocol import BrowserBackend
from .browser import AsyncSentienceBrowser
from .tracing import Tracer

Expand All @@ -90,7 +90,7 @@ class AgentRuntime:
to the tracer for Studio timeline display.

Attributes:
backend: BrowserBackendV0 instance for browser operations
backend: BrowserBackend instance for browser operations
tracer: Tracer for event emission
step_id: Current step identifier
step_index: Current step index (0-based)
Expand All @@ -99,16 +99,16 @@ class AgentRuntime:

def __init__(
self,
backend: BrowserBackendV0,
backend: BrowserBackend,
tracer: Tracer,
snapshot_options: SnapshotOptions | None = None,
sentience_api_key: str | None = None,
):
"""
Initialize agent runtime with any BrowserBackendV0-compatible browser.
Initialize agent runtime with any BrowserBackend-compatible browser.

Args:
backend: Any browser implementing BrowserBackendV0 protocol.
backend: Any browser implementing BrowserBackend protocol.
Examples:
- CDPBackendV0 (for browser-use via BrowserUseAdapter)
- PlaywrightBackend (future, for direct Playwright)
Expand Down Expand Up @@ -157,7 +157,7 @@ async def from_sentience_browser(
Create AgentRuntime from AsyncSentienceBrowser (backward compatibility).

This factory method wraps an AsyncSentienceBrowser + Page combination
into the new BrowserBackendV0-based AgentRuntime.
into the new BrowserBackend-based AgentRuntime.

Args:
browser: AsyncSentienceBrowser instance
Expand Down
70 changes: 70 additions & 0 deletions sentience/asserts/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
Assertion DSL for Sentience SDK.

This module provides a Playwright/Cypress-like assertion API for verifying
browser state in agent verification loops.

Main exports:
- E: Element query builder (filters elements by role, text, href, etc.)
- expect: Expectation builder (creates predicates from queries)
- in_dominant_list: Query over dominant group elements (ordinal access)

Example usage:
from sentience.asserts import E, expect, in_dominant_list

# Basic presence assertions
runtime.assert_(
expect(E(role="button", text_contains="Save")).to_exist(),
label="save_button_visible"
)

# Visibility assertions
runtime.assert_(
expect(E(text_contains="Checkout")).to_be_visible(),
label="checkout_visible"
)

# Global text assertions
runtime.assert_(
expect.text_present("Welcome back"),
label="user_logged_in"
)
runtime.assert_(
expect.no_text("Error"),
label="no_error_message"
)

# Ordinal assertions on dominant group
runtime.assert_(
expect(in_dominant_list().nth(0)).to_have_text_contains("Show HN"),
label="first_item_is_show_hn"
)

# Task completion
runtime.assert_done(
expect.text_present("Order confirmed"),
label="checkout_complete"
)

The DSL compiles to existing Predicate functions, so it works seamlessly
with AgentRuntime.assert_() and assert_done().
"""

from .expect import EventuallyConfig, EventuallyWrapper, ExpectBuilder, expect, with_eventually
from .query import E, ElementQuery, ListQuery, MultiQuery, in_dominant_list

__all__ = [
# Query builders
"E",
"ElementQuery",
"ListQuery",
"MultiQuery",
"in_dominant_list",
# Expectation builders
"expect",
"ExpectBuilder",
# Eventually helpers
"with_eventually",
"EventuallyWrapper",
"EventuallyConfig",
]
Loading