Python API¶
Everything the CLI does is available as a library. The high-level entry points are async.
import asyncio
from agentvision import analyze, load_settings
async def main():
report = await analyze("dist/index.html", settings=load_settings(vision_backend="local"))
print(report.verdict, [i.message for i in report.issues])
asyncio.run(main())
Confidential inputs (ephemeral cache)¶
Wrap any call in ephemeral_cache() so renders/sessions go to a throwaway temp dir that's
wiped on exit — nothing touches the on-disk cache. Use it for confidential artifacts:
from agentvision import analyze, ephemeral_cache, load_settings
async def main():
with ephemeral_cache(load_settings()) as settings:
report = await analyze("confidential.pptx", settings=settings)
# ... use report ...
# temp cache dir is removed here, even on error
Core functions¶
analyze
async
¶
analyze(source: str, *, settings: Settings | None = None, backend: str | None = None, instructions: str | None = None, expected: str | None = None, brief: Brief | None = None, use_ocr: bool = True, source_type: str = 'auto', viewport: Viewport | None = None, full_page: bool | None = None, wait_for: str | None = None, out_dir: Path | None = None) -> Report
Full visual analysis: structural grounding + vision-backend critique.
When brief is given, the render is also graded for intent conformance — does it
match what the agent set out to build — and the verdict is gated on it.
Motion sources (a video file or an animated GIF) are automatically routed to the
temporal grader (watch) — sampled over time, never flattened to a single frame or
mis-rendered by the browser.
check
async
¶
check(source: str, *, settings: Settings | None = None, brief: Brief | None = None, source_type: str = 'auto', viewport: Viewport | None = None, full_page: bool | None = None, wait_for: str | None = None, use_ocr: bool = True, out_dir: Path | None = None) -> Report
Classic checks only — no LLM, no API key, no egress (incl. OCR spell-check).
With a brief, also grades text requirements deterministically via OCR; non-text
requirements are reported uncertain (the offline path cannot judge visual intent).
Motion sources route to the temporal grader with the vision pass off (deterministic motion/black/dead-export signals only — still no LLM, no egress).
watch
async
¶
watch(source: str, *, settings: Settings | None = None, backend: str | None = None, frames: int | None = None, interval_ms: int | None = None, brief: Brief | None = None, instructions: str | None = None, use_vision: bool = True, source_type: str = 'auto', out_dir: Path | None = None) -> Report
Watch source over time and report temporal behavior (playback/loading/liveness).
render
async
¶
render(source: str, *, settings: Settings | None = None, source_type: str = 'auto', viewports: list[Viewport] | None = None, full_page: bool | None = None, wait_for: str | None = None, device_scale: float | None = None, settle_ms: int | None = None, freeze: bool | None = None, out_dir: Path | None = None) -> RenderResult
Render source and return image(s) plus trustworthy DOM/CV signals.
compute_diff ¶
compute_diff(baseline_path: str | Path, candidate_path: str | Path, out_path: str | Path | None = None) -> DiffResult
Sessions¶
LoopSession ¶
Drive the visual feedback loop for one artifact across iterations.
Agents call :meth:iterate after each fix attempt (optionally passing an updated
source). The session persists state under the workspace so it can be resumed.
run
async
¶
Convenience: iterate the SAME source up to max_iter times.
Useful for demonstrating stuck-detection on an unchanged artifact. Real agents
drive :meth:iterate themselves, editing the source between calls.
IterationResult ¶
Bases: BaseModel
GenerativeLoopSession ¶
Drive generate → perceive → refine until the output matches the brief.
Intent¶
Brief ¶
Bases: BaseModel
The intended product — the thought the artifact is graded against.
from_inputs
classmethod
¶
from_inputs(*, text: str | None = None, expect: list[str] | None = None, reference_image: str | None = None) -> Brief
Build a brief from CLI/REST-style inputs (--brief + repeated --expect).
IntentClaim ¶
Bases: BaseModel
A single checkable requirement extracted from the intent.
parse
classmethod
¶
Parse "must: the title reads AgentVision" → claim + importance.
The report contract¶
The verdict/report/intent types — Report, Issue, Brief, Conformance, Handoff,
BBox and friends — are the shared agentsensory
contract, re-exported from agentvision since 0.9.0. Every organ in the eyes/ears/brain
trio speaks this one language, so a Report the eyes grade drops straight onto the same
verdict bus the brain (Verel) consumes — no per-organ translation. from agentvision import
Report keeps working unchanged; the import surface is identical.
Report ¶
Bases: ReportBase
A vision report: shared fields + the render-specific surface.
Issue ¶
Bases: IssueBase
A vision issue: kind/source narrowed to the closed vision enums.
Conformance ¶
ClaimResult ¶
Bases: BaseModel
One requirement (a piece of the thought) graded against the artifact.
The handoff¶
Handoff ¶
Bases: BaseModel
The afferent signal: what a sense perceived, shaped for the brain to act on.
from_report
classmethod
¶
Distill any sense's Report into the actionable signal (duck-typed).
Backends¶
VisionBackend ¶
Bases: Protocol
complete_text
async
¶
Text-only completion (no image) — for checklist extraction + prompt refinement.
Backends that cannot do this (e.g. the offline local backend) return "".
AnalysisRequest ¶
Bases: BaseModel
Configuration¶
Settings ¶
Bases: BaseSettings
Runtime settings. Environment prefix: AGENTVISION_.
Provider API keys use their conventional env names (not the prefix) so they match what the provider SDKs already expect.
load_settings ¶
Build a Settings object, applying any explicit overrides last.
ephemeral_cache ¶
Yield a copy of settings whose cache lives in a throwaway temp dir, wiped on exit.
Use for confidential inputs so renders/sessions are never written to the persistent
on-disk cache. The temp dir is created with private (0700) permissions and removed in a
finally so it's cleaned up even on error.
with ephemeral_cache(load_settings()) as s:
report = await analyze("/path/to/confidential.pptx", settings=s)