soev_inspect
Show what each model call of a thread received, replayed from a trace store.
The command soev-inspect is the main interface: it lists, exports and inspects threads, as text or in the
browser. In Python, open a store by the same reference string as on the command line, and replay one thread. The
replay builds each request again with the code in this process, and asks no model to reply. The view that it
returns is JSON in an experimental format.
Stores
A reference string names a trace file, a directory of trace files, a SQLite file or a Postgres trace store.
opened
functionopened(ref) -> AbstractAsyncContextManager[TraceStore]Open the store that ref names, for as long as the context lasts.
ref is a reference string, the same string that names a source on the command line:
postgresql://…?schema=NAME: a Postgres trace store, schemasoevwhen none is named.- a path ending in
.db,.sqliteor.sqlite3: a SQLite trace store, created when missing. - any other path: one trace file, or a directory of them with its subdirectories, read into a store in memory.
A Postgres store also takes postgres://. It needs the postgres extra of soev-inspect, and it creates
no tables. In a directory, a .json file that is no trace file is skipped. A path that does not exist gives an
empty store in memory, without an error. A change to a store in memory reaches no file.
paramrefstrThe reference string.
Returns
AbstractAsyncContextManager[TraceStore]A context manager that gives the open store, and closes the store when the context ends.
Raises:
ValueError:refnames one file that is no trace file (pydantic.ValidationErroris one), or a trace file whose log is not sealed.
Replay a thread
The replay gives the view of a thread: its events, and each model call with the request that today's code builds.
load_thread
functionload_threadasync (store, thread_id, *, agents, resources=…, model=None) -> JsonRead thread_id from store and return its view, every model call replayed.
The replay builds the graph of each turn with the code in this process, and rebuilds the request of
each model call from the recorded events. It asks no model to reply. So the view shows what today's code sends,
which differs from what was sent when the agent changed since the thread ran. The command soev-inspect and its
page show the same view.
Example
from app.agents import AGENTS # your mapping from each agent name to its Agent
from soev_inspect import load_thread, opened
async with opened("traces.db") as store:
view = await load_thread(store, "thr-abc", agents=AGENTS)paramstoreTraceStoreThe trace store that holds the thread, for example from opened.
paramthread_idstrThe id of the thread.
paramagentsMapping[str, Agent[Any, Any]]The agents by name. The thread is replayed with the agent that its Opened event names.
paramresourcesOfflineResources= …The resources of the agent for its build. The default gives None, for agents that build
their graph without resources.
parammodelstr | None= NoneThe name of a model. Each turn is then rebuilt as if its input had named this model, to show the
request that the replay builds for that model. None rebuilds each turn with the model of its input.
Returns
JsonThe view of the thread, in the experimental format that Json describes.
Raises:
LookupError: The store holds no event of the thread.NotReplayableError: The thread has noOpenedevent that names its agent, oragentsdoes not hold that agent.soev_agents.runtime.UnknownEventTypeError: The thread holds an event of a type that its agent does not declare.soev_agents.domain.UnknownElementTypeError: The thread holds an element of a class that its agent does not declare.
OfflineResources
type aliasOfflineResources = Callable[[Agent[Any, Any]], Any]A function that returns the resources of one agent for a replay, which calls no store and no model.
load_thread calls it once with the agent of the thread, and gives the result to each build of that agent.
An adapter from soev_agents.runtime.refusing fits each resource. A refusing model gives no request "as sent". To
see that request, give a model adapter that implements soev_agents.ports.PreparesRequests: the replay asks it
to prepare each request, never to reply.
Json
type aliasJson = dict[str, JsonValue]A JSON object: the view of a thread that load_thread returns, or a part of that view.
The format of the view is experimental. Its keys can change in any release before a stable release. The page of
soev-inspect serve and the --json output of the text commands read the same format.
The view has these keys:
thread_idandagent: the thread, and the name of the agent that opened it.replayed_with: the code that did the replay.commitanddirtydescribe the git repository of the working directory, andframeworkis the version of soev-agents.commitandframeworkarenullwhen they are not known.events: each stored event of the thread in log order, with itsid(stream:seq), itspositionin the log, andcall: the index of the model call that the event records, from 0, ornull. The image data of a tool result is replaced by its size.calls: each model call, with itsid,node,model, timing,usage, andsame_request: whether the request that today's code builds has the recorded hash.builtholds the request that today's code builds, compared with the previous call.sentholds the request that the model adapter prepares to send, compared withbuilt, ornullwhen the adapter cannot show it.unreplayablesays why a call has nobuiltrequest.
NotReplayableError
errorNotReplayableErrorA thread that the given agents cannot replay.
load_thread raises it when the thread has no Opened event that names its agent, or when its agents
argument does not hold that agent.