Skip to content

Web UI

Local web UI to browse traces and experiments (FR-C4): agentlens ui.

:

agentlens ui                       # http://127.0.0.1:8765/, opens a browser
agentlens --db runs.db ui --port 9000 --no-open

From Python:

from agentlens.ui import UIApp, make_server, serve

server = make_server(UIApp("runs.db"), port=0)   # 0: any free port
print(server.url)
serve(server)                                    # until Ctrl+C

Pages: traces (filter by name, experiment, case, metadata, errors; paginated), one trace's span tree, experiments (baseline marked), an experiment's report and the comparison of two experiments (metrics with confidence intervals, optional gates, every case side by side). The pages reuse the HTML report's templates, CSS and trace viewer; /api/... serves the same data as JSON. Read-only, standard library server, no JavaScript framework, nothing loaded from the network.

DEFAULT_LIMIT module-attribute

DEFAULT_LIMIT = 50

Traces per page unless limit says otherwise.

MAX_LIMIT module-attribute

MAX_LIMIT = 500

Largest accepted limit.

DEFAULT_HOST module-attribute

DEFAULT_HOST = '127.0.0.1'

Loopback: the UI is reachable from this machine only.

HTTPError

HTTPError(status: int, message: str)

Bases: Exception

A request that cannot be served: 400 (bad parameter), 404, 405, 503, ...

Response dataclass

Response(status: int, body: bytes, content_type: str = _HTML, headers: dict[str, str] = dict())

An HTTP response: status, body and headers (Content-Type included).

text property

text: str

The body decoded as UTF-8.

UIApp

UIApp(db: str | PathLike[str], *, gates: Gates | None = None, resamples: int = DEFAULT_RESAMPLES, seed: int = 0, confidence: float = DEFAULT_CONFIDENCE)

The read-only web UI over one AgentLens database.

Parameters:

Name Type Description Default
db str | PathLike[str]

Path of the SQLite database. It is opened on the first request that needs it, and never created: while it does not exist, pages say so (status 503) instead of creating an empty database.

required
gates Gates | None

Gates checked on every comparison page (optional).

None
resamples int

Bootstrap resamples of the comparisons (the same default as agentlens compare); /compare takes it as a query parameter too.

DEFAULT_RESAMPLES
seed int

Bootstrap seed, as resamples.

0
confidence float

Confidence level of the intervals, as resamples.

DEFAULT_CONFIDENCE

close

close() -> None

Close the database connection (if it was opened).

store

store() -> SQLiteStore

The opened store; HTTPError 503 while the database does not exist.

handle

handle(method: str, target: str) -> Response

Serve one request; target is the request path with its query string.

UIServer

UIServer(app: UIApp, host: str, port: int)

Bases: ThreadingHTTPServer

A threading HTTP server for one UIApp (see make_server).

port property

port: int

The bound port (the real one when 0 asked for an ephemeral port).

url property

url: str

The UI's address, e.g. http://127.0.0.1:8765/.

host_allowed

host_allowed(host: str | None) -> bool

Whether a request's Host header is acceptable (always, off loopback).

make_server

make_server(app: UIApp, *, host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> UIServer

Bind a server for app (port=0 picks a free port); call serve_forever().

Raises:

Type Description
OSError

if the address cannot be bound (e.g. the port is in use).

serve

serve(server: UIServer, *, open_browser: bool = False) -> None

Serve until interrupted (Ctrl+C), optionally opening the UI in a browser first.

The socket is already listening, so the browser's first request waits in the queue until the loop starts. The server is closed on return.