jev-filter

Hosted execution

简体中文

New in 0.4: ambiguous operation/target/value choices return needs_review before execution (default top probability 0.55, margin 0.10). Independent --verify-controls checks unique current checked/pressed/selected/value states; invalid or stale final observations cannot prove completion. The observer supports explicit roleless controls, labelled transparent toggles and guarded nested vertical scrolling. New-tab following remains unsupported. See policy and integration examples.

Jev Filter can execute, not only filter. Three commands run a program-owned loop in which Jev chooses among options the program enumerated, the program acts, and the program checks the result:

Command Surface What it does
browse A web page (Chrome/Edge/Chromium over DevTools, or Camofox) Works toward a natural-language goal: clicks, typing supplied values, dropdowns, scrolling
desktop One Windows or macOS application The same loop over accessibility controls, with an OCR fallback for drawn UI
extract A web page Structures the page into records (table rows, blocks, links) and selects the relevant ones
survey Thousands of records Typed questions per record, aggregated in code into distributions, crosstabs and examples

Jev never produces text, selectors, coordinates, commands or scripts. Every executed target is a node the program observed; its identity and state are re-checked immediately before input.

How one step works

flowchart LR
  O[Observe: indexed controls + visible text] --> Q[One Jev request: operation + target per operation + value + irreversible?]
  Q --> G{Program gates}
  G -->|weak DONE/BLOCKED| Q
  G -->|pay/send/delete-like| P[Pause: needs_confirmation + token]
  G -->|no value for field| S[Skip field once; needs_value if stuck]
  G -->|ok| F[Freshness guard]
  F -->|changed| O
  F -->|same| X[Execute]
  X --> L[Log step] --> O

Browser: browse

jev-filter browse --url https://shop.example/ \
  --goal 'Search for red shoes in the Shoes category, in stock only' \
  --value query='red shoes' \
  --verify-url 'results.*cat=shoes'

Irreversible actions pause

Two independent signals mark an action irreversible: a keyword rule on commit-style controls (buttons, links, menu items; for example pay, place order, send, delete and their Chinese equivalents), and Jev's probability for the question "would the best next operation commit an effect the user cannot undo". Toggles, tabs and options are never gated. A gated action ends the run with the pending action and a confirm_token:

jev-filter browse --url https://shop.example/ --goal 'Buy the cheapest red shoes in size 42' \
  --value query='red shoes' --keep-open
# → {"status":"needs_confirmation","pending":{"label":"Place order"},
#    "confirm_token":"f25e…:e2","session":{"cdp_port":58111,"target_id":"0A92…"}}

# After the user approves:
jev-filter browse --cdp-port 58111 --target-id 0A92… --confirm f25e…:e2 \
  --goal 'Buy the cheapest red shoes in size 42' --verify-text 'order has been placed' --close-browser

The token binds the page fingerprint and the action; if anything changed, the confirmation is rejected as stale. By default the resumed run executes only the confirmed action, verifies and stops (--continue-after-confirm keeps going). --allow-irreversible disables the gate for a run.

The program appends one fixed sentence to the goal: irreversible steps are gated by the program, so keep advancing. Without it, goals ending in buy or place the order made Jev choose BLOCKED early (probability 0.46–0.60 in probes; 0.09–0.13 with the sentence).

Page data: extract

jev-filter extract --url 'https://shop.example/results?q=red' \
  --task 'In-stock shoes under $70' --analysis analysis.json

Tables become header-labelled rows (Product: Red Runner | Price: $59 | …); headings, list items, paragraphs and links become records with their nearest section. The records then go through the same contract as query, so selected_ids, review_ids, context admission and output projection behave identically. Nothing is clicked.

Desktop: desktop

pip install 'jev-filter[desktop] @ git+https://github.com/apixly-ai/jev-filter.git@v0.4.1'   # Windows: UI Automation + OCR; macOS: pyobjc
jev-filter desktop --list                  # candidate windows
jev-filter desktop --window '^Invoice Tool$' \
  --goal 'Set the customer name to Ada Lovelace, choose the Pro plan and save' \
  --value name='Ada Lovelace' --verify-text 'saved Ada Lovelace'

Desktop safety gates

These deterministic checks run before any Jev signal:

Many records: survey

jev-filter survey --input tickets.jsonl --spec survey.json --format md
{
  "task": "What do customers contact support about, how do they feel, and who may churn?",
  "keep": ["product"],
  "screen": {"instructions": "The record is a genuine support request (not spam)."},
  "questions": {
    "topic": {"type": "choice", "instructions": "Main topic?",
              "criteria": {"billing": "…", "bug": "…", "shipping": "…", "other": "…"}},
    "sentiment": {"type": "score", "instructions": "How does the customer feel?",
                  "criteria": ["Angry", "Neutral", "Positive"]},
    "churn": {"type": "noul", "instructions": "Threatens to cancel or switch."}
  },
  "group_by": ["topic", "product"],
  "confidence_floor": 0.6
}

Statuses and exit codes

Status Meaning Exit
done Goal reported done and every verifier passed 0
unverified DONE, but a verifier failed 2
needs_confirmation Next action is irreversible; pending and confirm_token included 2
needs_value A field needs a value that was not supplied 2
blocked No operation can progress; reason is challenge, login_required, model_blocked, no_progress or repeating 2
dry_run --dry-run: the decided action is in pending; nothing executed 2
origin_blocked Navigation left the allowed origins 2
budget_exhausted Step or decision budget reached 2
error Transport or provider failure; nothing was retried blindly 2

stdout carries a compact packet (status, trace of operations and labels, usage, verification). The archive file named in archive holds the full history, per-step decision distributions and latencies.

Limits