Polanyi
Synthetic shoppers hard-pinned to any website → recommendation-system event logs.
Point Polanyi at a URL. It runs a diverse set of Nemotron personas as on-site shoppers (search, compare, select, stop before PII/payment) and emits privacy-safe recsys_events for offline experiments.
Install
pip install polanyi
From source:
cd polanyi_agent_harness
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
Colab / product path (POLANYI_API_KEY)
import os
os.environ["POLANYI_API_KEY"] = "pk_live_..." # from Polanyi
from polanyi import Client
client = Client() # talks to https://api.polanyi.ai
result = client.simulate(site="https://www.nike.com", n=5, concurrency=5)
print(result.summary())
result.to_jsonl("nike_events.jsonl")
While the hosted API is warming up, point the SDK at your own server:
os.environ["POLANYI_API_KEY"] = "pk_live_dev"
os.environ["POLANYI_API_BASE_URL"] = "http://127.0.0.1:8080"
Local / power-user path (BROWSER_USE_API_KEY)
cp .env.example .env
# BROWSER_USE_API_KEY=bu_...
from polanyi import Client
client = Client() # uses Browser Use Cloud directly
result = client.simulate(
site="https://www.expedia.com",
n=10,
concurrency=5,
output_dir="runs/expedia",
)
print(result.summary())
result.to_jsonl("runs/expedia/merged.jsonl")
Agents are hard-pinned: they start on your site and must not leave that domain. External “Book with…” handoffs stop with checkout_boundary_stop (first-party-shaped data).
Host your own Polanyi API
The server wraps Browser Use behind POLANYI_API_KEY auth so end users never see bu_… keys.
pip install "polanyi[server]"
# mint a customer key
polanyi-serve --generate-key
# → pk_live_...
export POLANYI_API_KEYS=pk_live_...
export BROWSER_USE_API_KEY=bu_... # stays on the server only
polanyi-serve --host 0.0.0.0 --port 8080
Docker:
docker build -t polanyi-api .
docker run --rm -p 8080:8080 \
-e POLANYI_API_KEYS=pk_live_... \
-e BROWSER_USE_API_KEY=bu_... \
polanyi-api
API surface:
| Method | Path | Purpose |
|---|---|---|
GET |
/health |
Liveness |
POST |
/v1/simulations |
Start a job (Bearer pk_…) |
GET |
/v1/simulations/{id} |
Poll status + events |
CLI
# Any site, N diverse personas
polanyi-sim --site https://www.nike.com --batch 5 --concurrency 5 \
--output-dir output/nike_run
# Optional journey brief
polanyi-sim --site expedia.com --batch 10 --concurrency 10 \
--prompt "Browse hotels and flights; pick what fits your budget." \
--output-dir output/expedia_run
# Dry-run (personas only, no Browser Use)
polanyi-sim --site example.com --batch 3 --dry-run-persona --output-dir output/dry
Legacy (no --site) still works but is not hard-pinned.
Outputs
Each session directory contains:
| File | Purpose |
|---|---|
persona.json |
Synthetic identity |
browser_use_raw.json |
Raw Browser Use run |
recsys_events.jsonl / .parquet |
Ordered recsys events |
simulate_meta.json |
Site + run config (SDK / --site runs) |
simulate_plan.json |
Inferred vertical + per-persona journey goals |
How journeys are planned
Live runs (Client.simulate / polanyi-sim --site without --dry-run-persona):
- LLM diagnosis — a Browser Use agent opens the real site and returns an accurate JSON profile (
site_name,vertical,description,journey_templates) - Saved to
simulate_diagnosis.json - Each persona gets a different template from that diagnosis, personalized with their location/budget
Dry-runs skip the LLM and fall back to URL heuristics only.
from polanyi import diagnose_site, plan_journeys
from polanyi.personas import load_personas
diagnosis = diagnose_site("https://www.ticketnetwork.com")
print(diagnosis.site_name, diagnosis.vertical)
print(diagnosis.description)
plan = plan_journeys("https://www.ticketnetwork.com", load_personas(count=3), diagnosis=diagnosis)
Safety
- Synthetic actor IDs only (
syn_nmusa_*) training_use=offline_sandbox_only- Hard stop before identity / payment
- Hard site pin (first-party shaped)
Publish to PyPI
pip install build twine
python -m build
twine upload dist/*
The polanyi name is available on PyPI as of packaging time.
Roadmap
Schema, personas, Cloud runner, batch concurrencyPython SDKClient.simulate(site=…)+ hard pinLLM site diagnosis → diverse per-persona journeysPOLANYI_API_KEY+ self-hostable API wrapping Browser Use- Parse quality gates + JSON repair for agent output
- Hosted
api.polanyi.ai+ public PyPI release
Metadata
Release files for polanyi 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| polanyi-0.3.0.tar.gz | 35.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| polanyi-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 78.1 kB
Release files / polanyi-0.3.0.tar.gz
| Download URL | polanyi-0.3.0.tar.gz |
|---|---|
| Size | 35.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
728f98b0e8a3db39154f669646b9e0e6c6ccd9a92b14d4f31dc099f1a75f2b49
|
|
BLAKE2b-256 checksum How to use checksums |
d7d0e177ec9aaf76b913c1a10f601131b9dcb656ac78a53298715a1e4ff3b04a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Release files / polanyi-0.3.0-py3-none-any.whl
| Download URL | polanyi-0.3.0-py3-none-any.whl |
|---|---|
| Size | 42.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f71e8cdd12f4f44ea9bc85921433d11870fe5bc739ee9f7f27bbad1cc879e2ff
|
|
BLAKE2b-256 checksum How to use checksums |
6a962672fef1f711904f25c2bb311d1432a1e2aa15a353cca95e9febe95d6bbc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|