terx 0.1.0__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.
@@ -0,0 +1,38 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+ cache: 'pip'
24
+ cache-dependency-path: pyproject.toml
25
+
26
+ - name: Install dependencies
27
+ run: |
28
+ python -m pip install --upgrade pip
29
+ pip install -e ".[dev]"
30
+
31
+ - name: Lint with Ruff
32
+ run: |
33
+ pip install ruff
34
+ ruff check .
35
+
36
+ - name: Run tests with pytest
37
+ run: |
38
+ pytest tests/ -v
terx-0.1.0/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .pytest_cache/
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .terx/
9
+ .vcr/
10
+ .venv/
11
+ *.db
terx-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,359 @@
1
+ Metadata-Version: 2.4
2
+ Name: terx
3
+ Version: 0.1.0
4
+ Summary: Memory layer for browser agents — zero LLM tokens on repeated tasks. Writes .vcr files compatible with Agent VCR.
5
+ Project-URL: Homepage, https://github.com/ixchio/terx
6
+ Project-URL: Repository, https://github.com/ixchio/terx
7
+ Project-URL: Issues, https://github.com/ixchio/terx/issues
8
+ Author: ixchio
9
+ License: MIT
10
+ Keywords: agent-memory,browser-agent,browser-automation,browser-use,cdp,chrome-devtools-protocol,mcp,model-context-protocol,semantic-cache
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: aiohttp>=3.9
20
+ Requires-Dist: mcp>=1.0
21
+ Requires-Dist: mmh3>=4.0
22
+ Requires-Dist: websockets>=13.0
23
+ Provides-Extra: all
24
+ Requires-Dist: litellm>=1.0; extra == 'all'
25
+ Requires-Dist: numpy>=1.24; extra == 'all'
26
+ Requires-Dist: opencv-python-headless>=4.0; extra == 'all'
27
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'all'
28
+ Requires-Dist: pytest-benchmark>=4.0; extra == 'all'
29
+ Requires-Dist: pytest>=8.0; extra == 'all'
30
+ Requires-Dist: rich>=13.0; extra == 'all'
31
+ Requires-Dist: ruff>=0.4; extra == 'all'
32
+ Requires-Dist: scikit-image>=0.20; extra == 'all'
33
+ Requires-Dist: sentence-transformers>=3.0; extra == 'all'
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
36
+ Requires-Dist: pytest-benchmark>=4.0; extra == 'dev'
37
+ Requires-Dist: pytest>=8.0; extra == 'dev'
38
+ Requires-Dist: rich>=13.0; extra == 'dev'
39
+ Requires-Dist: ruff>=0.4; extra == 'dev'
40
+ Provides-Extra: embeddings
41
+ Requires-Dist: numpy>=1.24; extra == 'embeddings'
42
+ Requires-Dist: sentence-transformers>=3.0; extra == 'embeddings'
43
+ Provides-Extra: healing
44
+ Requires-Dist: litellm>=1.0; extra == 'healing'
45
+ Provides-Extra: vision
46
+ Requires-Dist: opencv-python-headless>=4.0; extra == 'vision'
47
+ Requires-Dist: scikit-image>=0.20; extra == 'vision'
48
+ Description-Content-Type: text/markdown
49
+
50
+ <div align="center">
51
+
52
+ # ⚡ TERX
53
+
54
+ ### Memory layer for browser agents.
55
+ **Your agent logs into Salesforce 50 times a day. TERX makes runs 2–50 cost zero tokens.**
56
+
57
+ <br>
58
+ <a href="https://github.com/ixchio/terx/actions/workflows/tests.yml"><img src="https://github.com/ixchio/terx/actions/workflows/tests.yml/badge.svg" alt="CI Status"></a>
59
+ <a href="https://pypi.org/project/terx/"><img src="https://img.shields.io/pypi/v/terx?style=flat-square&color=00d4aa&label=PyPI" alt="PyPI"></a>
60
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-yellow?style=flat-square" alt="License"></a>
61
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.11+-blue?style=flat-square" alt="Python"></a>
62
+ <a href="https://github.com/ixchio/agent-vcr"><img src="https://img.shields.io/badge/Works%20with-Agent%20VCR-purple?style=flat-square" alt="Works with Agent VCR"></a>
63
+ <br><br>
64
+
65
+ ```bash
66
+ pip install terx
67
+ ```
68
+
69
+ No Playwright. No Selenium. Raw CDP. Works with Agent VCR.
70
+
71
+ <br>
72
+
73
+ </div>
74
+
75
+ ---
76
+
77
+ ## The Problem
78
+
79
+ Every browser agent today is amnesiac.
80
+
81
+ Run your agent 50 times on the same login flow. It re-discovers the login button all 50 times.
82
+ Burns LLM tokens re-discovering the login button all 50 times.
83
+
84
+ ```
85
+ Run 1: LLM finds login button → clicks → succeeds [$0.008 · 2,100 tokens · 3.2s]
86
+ Run 2: LLM finds login button → clicks → succeeds [$0.008 · 2,100 tokens · 3.1s]
87
+ Run 3: LLM finds login button → clicks → succeeds [$0.008 · 2,100 tokens · 3.3s]
88
+ ...
89
+ Run 50: LLM finds login button → clicks → succeeds [$0.008 · 2,100 tokens · 3.0s]
90
+
91
+ Total: $0.40 · 105,000 tokens · 2.6 minutes — for the SAME task repeated 50 times
92
+ ```
93
+
94
+ **With TERX:**
95
+
96
+ ```
97
+ Run 1: Agent runs normally → TERX records CDP commands [$0.008 · 2,100 tokens]
98
+ Run 2: TERX replays → done [$0.000 · 0 tokens · 40ms]
99
+ Run 3: TERX replays → done [$0.000 · 0 tokens · 38ms]
100
+ ...
101
+ Run 50: TERX replays → done [$0.000 · 0 tokens · 41ms]
102
+
103
+ Total: $0.008 · 2,100 tokens — 98% cost reduction
104
+ ```
105
+
106
+ ---
107
+
108
+ ## How It Works
109
+
110
+ <div align="center">
111
+ <img src="docs/assets/architecture.svg" alt="TERX Architecture Flow" width="100%">
112
+ </div>
113
+
114
+ Three components:
115
+
116
+ 1. **CDP Bridge** — raw `asyncio` WebSocket to Chrome. No Playwright. No browser testing framework overhead. Single-digit ms execution.
117
+
118
+ 2. **DOM Extractor** — reads the accessibility tree (not raw HTML). Assigns stable numeric IDs to interactable elements. Computes a fuzzy structural hash that survives minor CSS changes.
119
+
120
+ 3. **Muscle Memory Cache** — SQLite-backed. On successful task completion, stores the CDP command sequence keyed by `(domain, dom_hash)`. On future runs, replays directly. Writes `.vcr` files.
121
+
122
+ 4. **Self-Healing Replay & SSIM Audits** — If the DOM drifts, TERX evaluates the new state via LLM to heal the parameters without dropping back to a full agent evaluation. Every replay takes a snapshot and computes the Structural Similarity Index (SSIM) to warn agents of silent visual UI drift.
123
+
124
+ ---
125
+
126
+ ## Quick Start
127
+
128
+ ### 1. Start Chrome with debugging enabled
129
+
130
+ ```bash
131
+ google-chrome --remote-debugging-port=9222 --no-first-run
132
+ # or for headless:
133
+ google-chrome --remote-debugging-port=9222 --headless=new
134
+ ```
135
+
136
+ ### 2. Connect TERX
137
+
138
+ ```python
139
+ import asyncio
140
+ from terx.cdp.session import BrowserSession
141
+ from terx.cache.cache import MuscleMemorycache, session_for
142
+
143
+ cache = MuscleMemorycache()
144
+
145
+ async def run_task():
146
+ async with BrowserSession() as session:
147
+ bridge = session.bridge()
148
+
149
+ async with session_for(cache, bridge, "login to salesforce") as ctx:
150
+ if ctx.hit:
151
+ # Run 2+: zero LLM tokens, 40ms
152
+ await ctx.replay()
153
+ else:
154
+ # Run 1: your agent runs normally
155
+ # Transparent CDP Proxy auto-records all commands!
156
+ await your_agent.run("login to salesforce")
157
+
158
+ print(ctx.ledger)
159
+ # 💾 Cache HIT · 12 commands · 41ms · ~12 LLM calls saved · run #3
160
+
161
+ asyncio.run(run_task())
162
+ ```
163
+
164
+ ### 3. Or use the MCP server (connect any AI agent)
165
+
166
+ ```bash
167
+ terx-server
168
+ ```
169
+
170
+ Add to Claude Desktop / Cursor `mcp.json`:
171
+
172
+ ```json
173
+ {
174
+ "mcpServers": {
175
+ "terx": {
176
+ "command": "terx-server"
177
+ }
178
+ }
179
+ }
180
+ ```
181
+
182
+ Available MCP tools:
183
+
184
+ | Tool | What it does |
185
+ |---|---|
186
+ | `browser_get_state` | AXTree snapshot — elements with stable IDs |
187
+ | `browser_navigate` | Navigate to URL |
188
+ | `browser_click` | Click element by ID |
189
+ | `browser_type` | Type into input (React/Vue safe) |
190
+ | `browser_screenshot` | Returns hash ref, NOT base64 blob |
191
+ | `browser_scroll` | Scroll up/down |
192
+ | `browser_new_tab` | Open new tab |
193
+ | `cache_stats` | Hit rate, savings, domains |
194
+ | `cache_invalidate` | Clear cache for a domain |
195
+
196
+ ---
197
+
198
+ ## Works with Agent VCR
199
+
200
+ TERX writes browser sessions in `.vcr` format — the same format used by [Agent VCR](https://github.com/ixchio/agent-vcr).
201
+
202
+ ```python
203
+ # Every TERX session writes a .vcr file automatically
204
+ # .vcr/browser_salesforce_1234567890.vcr
205
+
206
+ # Load it in Agent VCR for time-travel debugging:
207
+ from agent_vcr import VCRPlayer
208
+
209
+ player = VCRPlayer.load(".vcr/browser_salesforce_1234567890.vcr")
210
+
211
+ # See exactly what happened at each step
212
+ print(player.goto_frame(3))
213
+ # {'cdp_method': 'Input.dispatchMouseEvent', 'cdp_params': {...}, ...}
214
+
215
+ # See what the cache hit rate was
216
+ print(player.get_total_cost()) # 0.0 on replay runs
217
+ ```
218
+
219
+ **Agent VCR** → undo filesystem damage from coding agents.
220
+ **TERX** → zero-token memory for browser agents.
221
+ Same `.vcr` format. Same `VCRPlayer`. Different problems.
222
+
223
+ ---
224
+
225
+ ## Why Not Playwright?
226
+
227
+ Playwright is a testing framework. TERX is an execution layer.
228
+
229
+ | | Playwright | TERX |
230
+ |---|---|---|
231
+ | Purpose | Browser testing | AI agent execution |
232
+ | Protocol | CDP (wrapped) | CDP (raw) |
233
+ | Overhead | ~120MB RAM per subprocess | ~2MB |
234
+ | Startup | 800ms–2s | <50ms |
235
+ | Memory across runs | None | Muscle memory cache |
236
+ | MCP integration | External wrapper needed | Built-in |
237
+ | `.vcr` output | ❌ | ✅ |
238
+
239
+ ---
240
+
241
+ ## The `.vcr` File Format
242
+
243
+ Plain JSONL. Human-readable. Git-diffable. Agent VCR compatible.
244
+
245
+ ```jsonl
246
+ {"type": "session", "data": {"session_id": "browser_salesforce_...", "agent_type": "browser", "tool": "terx", "task": "login to salesforce", "domain": "salesforce.com", "cache_hit": true}}
247
+ {"type": "frame", "data": {"node_name": "page_navigate", "input_state": {"cdp_method": "Page.navigate", "cdp_params": {"url": "https://salesforce.com/login"}}, "output_state": {"cdp_result": {...}}, "metadata": {"latency_ms": 145, "cache_hit": true}}}
248
+ {"type": "frame", "data": {"node_name": "input_dispatchmouseevent", "input_state": {"cdp_method": "Input.dispatchMouseEvent", ...}, "metadata": {"latency_ms": 8, "cache_hit": true}}}
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Security
254
+
255
+ TERX applies scheme-first URL validation before any navigation:
256
+
257
+ ```python
258
+ # Blocked automatically:
259
+ browser_navigate("data:text/html,<script>...") # data: bypass → blocked
260
+ browser_navigate("javascript:alert(1)") # JS injection → blocked
261
+ browser_navigate("file:///etc/passwd") # local file → blocked
262
+
263
+ # Allowed:
264
+ browser_navigate("https://salesforce.com") # ✅
265
+ browser_navigate("http://localhost:3000") # ✅
266
+ ```
267
+
268
+ Screenshots return hash references, not raw base64 blobs — preventing context poisoning where large images consume your entire LLM context window.
269
+
270
+ ---
271
+
272
+ ## Benchmarks
273
+
274
+ ```
275
+ Coming in v0.2: 100-task benchmark vs browser-use baseline.
276
+ Preliminary numbers from manual testing:
277
+
278
+ Task | Run 1 (cold) | Run 2+ (cached) | Savings
279
+ ─────────────────────────────────────────────────────────────────────
280
+ Login (12 CDP commands) | 3.2s · $0.008 | 41ms · $0.000 | 99%
281
+ Form fill (8 commands) | 2.1s · $0.005 | 28ms · $0.000 | 99%
282
+ Search + click (6 cmds) | 1.8s · $0.004 | 21ms · $0.000 | 99%
283
+ ```
284
+
285
+ ---
286
+
287
+ ## Roadmap
288
+
289
+ - [x] Raw CDP bridge (no Playwright)
290
+ - [x] Accessibility tree extractor
291
+ - [x] Fuzzy DOM structural hasher
292
+ - [x] Muscle memory cache (SQLite)
293
+ - [x] `.vcr` output (Agent VCR compatible)
294
+ - [x] FastMCP Server with 10 tools
295
+ - [x] Framework-adaptive input (React/Vue safe)
296
+ - [x] Screenshot hash refs (no context poisoning)
297
+ - [x] Self-healing replay (fallback to LLM on DOM drift, auto-update cache)
298
+ - [x] Visual Audits via SSIM (Structural Similarity Index)
299
+ - [x] Transparent CDP Recording Proxy (zero manual setup)
300
+ - [ ] MutationObserver cache invalidation
301
+ - [ ] Local embedding-based element lookup (`sentence-transformers`)
302
+ - [ ] browser-use integration wrapper
303
+ - [ ] Benchmark suite (100 tasks, published results)
304
+
305
+ ---
306
+
307
+ ## Install
308
+
309
+ ```bash
310
+ # Core (CDP bridge + cache + MCP server)
311
+ pip install terx
312
+
313
+ # With local embeddings for semantic element lookup
314
+ pip install "terx[embeddings]"
315
+
316
+ # With visual SSIM auditing and LLM-powered self-healing
317
+ pip install "terx[vision,healing]"
318
+ ```
319
+
320
+ ---
321
+
322
+ ## Contributing
323
+
324
+ ```bash
325
+ git clone https://github.com/ixchio/terx
326
+ cd terx
327
+ pip install -e ".[dev]"
328
+ pytest tests/ -v
329
+ ```
330
+
331
+ ---
332
+
333
+ ## License
334
+
335
+ MIT
336
+
337
+ ---
338
+
339
+ <div align="center">
340
+
341
+ ### ⚡
342
+
343
+ **Run 1 costs tokens. Run 2 costs nothing.**
344
+
345
+ <br>
346
+
347
+ ```bash
348
+ pip install terx
349
+ ```
350
+
351
+ <br>
352
+
353
+ Works with [Agent VCR](https://github.com/ixchio/agent-vcr) — time-travel debugging for AI agents.
354
+
355
+ <br>
356
+
357
+ <sub>Built by <a href="https://github.com/ixchio">ixchio</a> · MIT License</sub>
358
+
359
+ </div>