Metadata-Version: 2.5
Name: nova-ufast-agent
Version: 0.1.0
Summary: An ultrafast browser agent with a dynamic, indexed action space.
Project-URL: Homepage, https://github.com/browser-use/jev-ultrafast
Project-URL: Source, https://github.com/browser-use/jev-ultrafast
Project-URL: Documentation, https://github.com/browser-use/jev-ultrafast
Author: Tanmay Somani
License: MIT
License-File: LICENSE
Keywords: agent,automation,browser,browser-agent,llm,typesafe,web-automation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Requires-Dist: browser-harness==0.1.13
Requires-Dist: httpx[http2]<1,>=0.28
Description-Content-Type: text/markdown

# Nova UFast Agent ⚡

**A browser agent with a dynamic, indexed action space.**

Give it one goal. A decision model (TypeSafe) picks an operation **and** an element in a single request. A small LLM writes text only when the operation is `TYPE_TEXT`. Every other action is executed by code against real observed DOM nodes — the model never emits selectors, coordinates, or executable JavaScript.

> Derived from [browser-use/jev-ultrafast](https://github.com/browser-use/jev-ultrafast) (MIT). Rebranded, repackaged, and shipped with a rebuilt local inspector UI.

## How it thinks

Every observation produces a fresh element table:

```text
[1] button    Change ticket type · Round trip
[2] combobox  Where from?        · San Francisco
[3] combobox  Where to?          · empty
[4] textbox   Departure          · empty
...
```

The operations are `CLICK`, `TYPE_TEXT`, `SELECT`, `SCROLL_UP`, `SCROLL_DOWN`, `WAIT`, `DONE`, and `BLOCKED`. Only supported operations and targets are offered.

```text
                     one decision request
                    ┌───────────────────────────┐
page → element table → operation                │
                    │ click_target              │
                    │ type_text_target          │
                    │ select_target, if present │
                    └─────────────┬─────────────┘
                        use the matching target
                                  │
                   CLICK [7] ─────┤──→ browser
               TYPE_TEXT [3] ─────┘
                         ↓
                  small LLM → text → browser
```

Target questions are speculative: if the operation is `CLICK`, only `click_target` can execute. Two decisions, **one network round trip**. Each target head contains only compatible elements. Native dropdown choices carry an observed element/option index.

## Quickstart

```bash
git clone <your-repo> nova-ufast-agent
cd nova-ufast-agent
uv sync
cp .env.example .env
# Add TYPESAFE_API_KEY and TEXT_MODEL_API_KEY.
uv run nova-ufast
```

Open **http://127.0.0.1:8766** and click **Start demo**. The inspector shows numbered elements, operation probabilities, target probabilities, and the executed action trail. **Choose next** pauses before execution.

Chrome connects through [Browser Harness](https://github.com/browser-use/browser-harness), installed by `uv sync`. Run `uv run browser-harness --doctor` if it needs connecting. Allow remote debugging in Chrome when prompted.

## Use the library

```python
from nova_ufast_agent import Agent

with Agent(
    "https://www.google.com/travel/flights?hl=en",
    "Find one-way flights from Zurich to London on September 20, 2026, "
    "for one adult in economy. Stop when matching flight options are visible.",
) as agent:
    for state in agent.run():
        print(state["elapsed_ms"], state["status"])
```

Run with `uv run --env-file .env python your_script.py`. The same policy can run a different task:

```bash
uv run --env-file .env python examples/run.py \
  --url https://en.wikipedia.org/wiki/Main_Page \
  --goal 'Find and open the Wikipedia article about Gödel’s incompleteness theorems.'
```

`uv run --env-file .env python examples/flights.py --keep-open` performs a live Google Flights search, independently checks the resulting route/date/results, and saves its trace. It never selects or books a flight.

Install it as a normal dependency:

```bash
uv pip install .      # editable: uv pip install -e .
python -m build       # or: uv build
```

## Environment

| Variable | Required | Purpose |
| --- | --- | --- |
| `TYPESAFE_API_KEY` | ✅ | Decisions: operation + target heads |
| `TYPESAFE_MODEL` | – | Default `jev-latest` |
| `TEXT_MODEL_API_KEY` | for `TYPE_TEXT` | OpenAI-compatible text helper |
| `TEXT_MODEL_BASE_URL` | – | Default `https://api.deepseek.com/v1` |
| `TEXT_MODEL` | – | Default `deepseek-chat` |
| `TEXT_MODEL_REASONING` | – | `none` disables reasoning on compatible providers |

Credentials stay server-side and `.env` is git-ignored.

## Why it moves

- **One request per decision cycle.** Operation and target heads share the same observed state.
- **No screenshots in the default agent loop.** The model consumes structured state; the inspector opts into screenshots.
- **One browser call per snapshot.** Visible controls, names, values, and text are read atomically with references to the actual DOM nodes.
- **Validate the selected target.** Clicks re-check the document, form values, target, and nearby context. Geometry is resolved and covered controls are rejected before input.
- **Wait for useful state.** After typing into a combobox, suggestions are awaited (capped at 200 ms). Other interactions get at most two animation frames or 50 ms.
- **Keep hidden tabs rendering.** Focus emulation prevents background throttling without switching Chrome's visible tab.
- **Send visible text only.** Offscreen bodies and footers do not fill the model context.
- **Reuse an interrupted text request.** A generated value survives a stale-page retry only while the entire text-helper input is unchanged.

Every executed target resolves from an observed node. The executor rechecks freshness and click occlusion. Model output never becomes selectors, coordinates, shell commands, or executable JavaScript. Text-helper output must parse as a small JSON object before typing.

## Structure

| File | Job |
| --- | --- |
| `nova_ufast_agent/agent.py` | The complete loop and text-helper handoff |
| `nova_ufast_agent/snapshot.js` | Atomic DOM snapshot, indexed controls, freshness guards |
| `nova_ufast_agent/browser.py` | Browser connection, current geometry, execution |
| `nova_ufast_agent/model.py` | Dynamic operation/target heads and text generation |
| `nova_ufast_agent/questions.py` | Model instructions |
| `nova_ufast_agent/demo.py` | Local inspector server |

## Limits

`DONE` still requires independent outcome verification. The DOM reader handles common HTML and ARIA controls, not the full accessible-name specification. Shadow roots, frames, canvas, uploads, pop-up tabs, nested scrolling, and arbitrary keyboard widgets are out of scope for this MVP. Owned tabs share the existing Chrome profile.

## Development

```bash
uv run ruff check .
uv run pytest
node --check nova_ufast_agent/static/app.js
node --check nova_ufast_agent/snapshot.js
uv build
```

Tests are offline and never call paid APIs.

## License

MIT. Original copyright (c) 2026 Browser Use for the upstream `jev-ultrafast` project, from which this library is derived.