OSS quickstart

From install to a standing watch.

The core is pure Python standard library: install, then run offline with deterministic fake backends and no API keys. Providers are opt-in extras behind vendor-neutral seams.

01 · Install the core

The distribution name is percept-vision; the Python import is percept. The package imports cleanly with no key and nothing extra installed — vendor SDKs are lazy-imported only inside adapter methods.

TerminalApache-2.0 package
python3 -m venv .venv
source .venv/bin/activate
pip install percept-vision
python -c "import percept"

Preview: the WATCH_VERSION 1.1.0 / WatchPlan surface on this page is the version pinned for Percept Cloud. The public PyPI package can lag it — until a matching wheel is published, pin the version your build targets and treat these snippets as the Cloud-pinned preview rather than a released API. See release status.

02 · The watch() one-liner

watch() is the frozen high-level entrypoint (WATCH_VERSION = "1.1.0"). Goals are plain-language strings, Goal objects, WatchPlans, or any mix — the condition is carried verbatim to the judge, never compiled to a rigid predicate. A frame that changes nothing yields zero events; one WatchEvent is yielded per gate FIRE or ASK.

Pythonwatch() · WATCH_VERSION 1.1.0
import percept

async for event in percept.watch(stream, "the kettle boils"):
    handle(event)  # WatchEvent — one per gate FIRE or ASK; silent frames yield nothing

03 · Offline, deterministic, no API keys

The deterministic fakes (FakeVision, FakeConductor, FakeSTT, FakeTTS) call no network and need no credential — the whole cognition path runs on your machine.

PythonOffline lane
from percept import Percept

agent = Percept.create(mode="offline")     # scripted/fake seams — no keys, no network
verdict = await agent.perceive_judged(frame)

The safety posture is loud, not silent: in LIVE mode an unset vision backend — or a real backend with its credential missing — raises a ModeError naming the exact env var to set. You can never silently land on a fake and mistake it for success.

04 · percept.run and RuntimeSession

percept.run(...) is the batteries-included front door: it opens a video or audio source, drives the cognition core over frames, and delivers durable incidents — idempotent, deduped by incident id. percept.start(...) returns a RuntimeSession with the interactive inputs: ask, interrupt, arm/disarm, pause/resume, label.

PythonRuntime front door
import percept

async for incident in percept.run(
    source="kitchen.mp4",                  # camera index, file, or RTSP — or any frame iterable
    goals=["the milk is boiling over"],
    fps=4.0,
    on_ask=handle_ask,                     # low-confidence refusals — asks are not incidents
):
    notify(incident)                       # a durable Incident, deduped on redelivery

05 · Real providers, when you opt in

Frontier backends (Anthropic, Gemini, Deepgram, OpenRouter) sit behind the vendor-neutral Vision seam as opt-in extras. The rule is the identity/configuration split: the provider name is the adapter's identity; the model id is configuration carried to it, never its identity.

Pythonresolve_vision · provider seam
# Provider name is identity; the model id is configuration.
resolve_vision("claude", model=...)       # Anthropic adapter — needs its key + extra
resolve_vision("gemini", model=...)
resolve_vision("openrouter", model=...)
resolve_vision("scripted")                # deterministic fake — no key, no network

06 · Version contracts