Run viewer¶
Record runs to a folder and browse them on 127.0.0.1 (agent-adapter ui), or chat with an agent there. Guides: See your runs, Chat with your agent, See your evals.
agent_adapter.viewer¶
Run viewer: record runs to JSONL files, browse them and chat locally (agent-adapter ui).
DEFAULT_FOLDER = '.agent_adapter/runs'
module-attribute
¶
LOOPBACK = '127.0.0.1'
module-attribute
¶
ApprovalDesk
¶
Decides tool approvals in a SQLiteApprovalStore file; it never runs a tool.
The app's own executor.resume(approval_id) later runs the call with this decision.
Raises:
| Type | Description |
|---|---|
ConfigError
|
no database at |
decide(approval_id, *, approved, reason='')
¶
Record approve or deny as this desk's reviewer; only a pending tool record.
Raises:
| Type | Description |
|---|---|
ApprovalNotFound
|
unknown id. |
ApprovalAlreadyDecided
|
the record is no longer pending (here or by a race). |
ToolUsageError
|
a flow-node record, or one the HTTP tool server parked. |
pending()
¶
Pending records, newest first, masked, each with similar past decisions (advice).
Recorder
¶
Writes events under folder, one segment file per run and process (append-only).
emit only queues: a background thread writes, in batches, so the event loop never waits
on the disk. A full queue drops events (counted, logged). Queued events are written at
flush, close and interpreter exit. Tool and LLM content keys are left out unless
capture_content; secret-named values are always masked. Past keep_runs the oldest
ended runs are deleted; a run stops recording after max_events_per_run events.
Raises:
| Type | Description |
|---|---|
ConfigError
|
a bad limit, or a folder that cannot be made. |
wants_confirm_content
property
¶
Also asks for confirm tools' results (opt-in on top of capture_content).
wants_content
property
¶
Asks native calls for their content (arguments, results, messages, flow state).
close(timeout=5.0)
¶
Write what is queued and stop the writer; later events start a new one.
flush(timeout=5.0)
¶
Wait until every queued event is written; False on timeout.
registry()
¶
The registry whose catalogue each run file starts with.
stop(timeout=5.0)
¶
Detach from every executor record() attached it to, write what is queued, and stop.
Later events are ignored. False when the queue was not written within timeout.
take_flow_graph(run_id, flow, graph)
¶
Write a flow's graph once into its run's file (FlowRunner calls this).
RunFolder
¶
A runs folder, or a single run file, read again on each refresh from where it stopped.
Raises:
| Type | Description |
|---|---|
ConfigError
|
|
tags_folder
property
¶
Where the run tag sidecars live: the runs folder, or the run file's folder.
detail(key, since=0, *, paged=True)
¶
One run: summary, graphs, tools, spans with lanes, and events since (paged).
None for an unknown run.
refresh()
¶
Pick up new runs and new lines; deleted (rotated) runs are dropped.
Raises:
| Type | Description |
|---|---|
OSError
|
the folder cannot be listed. |
search_folds()
¶
Copies of the search folds of each run's segments, by run key (safe to read later).
summaries()
¶
One summary per run, newest first.
ViewerServer
¶
Bases: ThreadingHTTPServer
A ThreadingHTTPServer holding the runs folder, the approval desk and its secrets.
token travels in the URL fragment of url (never sent to a server, a log or a Referer);
the page keeps it in sessionStorage and sends it as X-AA-Token on every /api/ call.
csrf guards decisions on top. Both are new on every start. The HTML shell and its static
files hold no secret and are public.
assign_lanes(spans)
¶
Give each span the lowest free lane at its start (greedy interval colouring).
build_spans(events)
¶
One span per call (tool, LLM, node, flow, compression), in start order, with lanes.
check_host(host)
¶
Refuse any bind address but the IPv4 loopback.
Raises:
| Type | Description |
|---|---|
ConfigError
|
|
import_otlp(source, folder)
¶
Write one run file per trace of the OTLP JSON file source into folder; run keys back.
Importing the same file again rewrites the same run files.
Raises:
| Type | Description |
|---|---|
ConfigError
|
|
OSError
|
|
make_server(target, *, host=LOOPBACK, port=DEFAULT_PORT, approvals=None, reviewer='', chat=None, evals=DEFAULT_EVALS_FOLDER, cases_dir=DEFAULT_CHAT_DIR)
¶
A bound, not yet serving, viewer server (port=0 picks a free port); chat turns chat on.
evals is the folder of saved eval reports the Evals view lists; runs saved as eval
cases go to the chat's eval_cases.jsonl, or without chat to the one in cases_dir.
Raises:
| Type | Description |
|---|---|
ConfigError
|
a non-loopback |
OSError
|
the port is taken. |
record(executor=None, *, folder=DEFAULT_FOLDER, capture_content=False, keep_runs=200, source='', capture_confirm_content=False)
¶
Record every run of executor under folder.
With no executor it follows the default executor, also after aa.configure replaces it.
Calling it again for the same target and folder returns the recorder already attached;
recorder.stop() detaches it again.
Raises:
| Type | Description |
|---|---|
ConfigError
|
a bad |
serve(agent=None, *, model=None, registry=None, executor=None, folder=DEFAULT_FOLDER, port=DEFAULT_PORT, open_browser=True, system='', max_steps=8, turn_timeout=300.0, approval_timeout=600.0, reviewer='local', chat_dir=DEFAULT_CHAT_DIR, stream=True, evals=DEFAULT_EVALS_FOLDER, user_id='', memory=None, memory_save='none', memory_every=1, recall_k=5, out=None)
¶
Chat with agent (or the built-in loop over model and registry) in the viewer.
Blocks until Ctrl+C. Turns are recorded into folder, so the Runs view shows them.
open_browser opens a one-use launch link (valid 60 s); stream=False
makes the built-in loop call generate (so an LLM response cache applies). The Evals
view lists the reports saved in evals. user_id owns the chats; with memory, turns
recall that user's records across chats and memory_save ("summary", "facts" or the
default "none") saves new ones every memory_every turns.
Raises:
| Type | Description |
|---|---|
ConfigError
|
neither or both of |
OSError
|
the port is taken. |
Also exported here, documented under the canonical path: Attachment, ChatAgent, ChatMessage, ChatSession.
agent_adapter.viewer.chat¶
Chat with an agent in the viewer: the contract types an agent receives and returns.
chat_agent_task(agent, executor)
¶
fn(task, ctx) that runs agent(message, session) in the calling run; chunks are joined.
Also exported here, documented under the canonical path: Attachment, ChatAgent, ChatMessage, ChatReply, ChatSession.