provrun.backends
Every backend has the same asynchronous lifecycle, because a remote backend, such as Foundry, starts a run, is asked about it later, and can cancel it:
handle = await backend.start(ctx, agent, run)
await backend.poll(handle) # "running", "completed", "failed" or "cancelled"
result = await backend.result(handle)
await backend.cancel(handle)InProcessBackend runs the agent as an asyncio task in this process, so
start returns at once and result waits for the task. It writes
sandbox_started and sandbox_completed around the run.
class RunResult
RunResult(output: str, duration: float, usage: dict[str, int] = <factory>, data: dict[str, Any] = <factory>)What a backend returns from one run.
| Parameter | Type | Default | Description |
|---|---|---|---|
output |
str | required | The agent’s answer, as text |
duration |
float | required | The run’s time in seconds; an in-process backend sets it |
usage |
dict[str, int] | <factory> |
The token counts, such as input_tokens and output_tokens |
data |
dict[str, Any] | <factory> |
More that a backend reports; the built-in backends leave it empty |
class Pieces
Pieces()The pieces of one streamed model request: when the first came, and the text so far.
If the request fails partway, its step_failed holds the text that was
already handed on, so the evidence has all that a viewer saw. A backend
sets RunContext.pieces to the request’s Pieces.
Pieces.add
Pieces.add(piece: str) -> NoneKeep one piece, and the time to it in milliseconds if it is the first.
| Parameter | Type | Default | Description |
|---|---|---|---|
piece |
str | required | One piece of the reply’s text |
Pieces.record
Pieces.record(data: dict) -> NonePut the time to the first piece, if any came, into a step’s data.
| Parameter | Type | Default | Description |
|---|---|---|---|
data |
dict | required | A step’s data, which gets first_token_ms |
Pieces.failed
Pieces.failed(step: Any) -> NonePut what came before a failure into the step that failed.
The step’s data gets first_token_ms and the number of pieces, and its payload the partial response, when there was text.
| Parameter | Type | Default | Description |
|---|---|---|---|
step |
Any | required | The evidence Step of the request that failed |
class RunHandle
RunHandle(run_id: str, backend: str, task: asyncio.Task | None = None, remote_id: str | None = None)A run that a backend has started, as start returns it.
| Parameter | Type | Default | Description |
|---|---|---|---|
run_id |
str | required | The run’s ID |
backend |
str | required | The backend’s name |
task |
asyncio.Task | None | None |
The task of an in-process run |
remote_id |
str | None | None |
A remote backend’s own ID for the run |
class Backend
Runs an agent spec in one place, with the lifecycle the module shows.
A spec names its backend by the name it is registered under in the entry point group provrun.backends.
Backend.start
async Backend.start(ctx: RunContext, agent: AgentSpec, run: RunSpec) -> RunHandleStart one run.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
RunContext | required | The run; its recorder takes the evidence |
agent |
AgentSpec | required | The agent to run |
run |
RunSpec | required | The staged inputs and the run’s folders |
| returns | RunHandle | The handle of the started run |
Backend.poll
async Backend.poll(handle: RunHandle) -> strTell how a run stands.
| Parameter | Type | Default | Description |
|---|---|---|---|
handle |
RunHandle | required | The handle that start returned |
| returns | str | “running”, “completed”, “failed” or “cancelled” |
Backend.result
async Backend.result(handle: RunHandle) -> RunResultWait for a run to end, and give its result.
| Parameter | Type | Default | Description |
|---|---|---|---|
handle |
RunHandle | required | The handle that start returned |
| returns | RunResult | What the run gave back; it raises what the run raised |
Backend.cancel
async Backend.cancel(handle: RunHandle) -> NoneStop a run.
| Parameter | Type | Default | Description |
|---|---|---|---|
handle |
RunHandle | required | The handle that start returned |
Backend.stream
Backend.stream(handle: RunHandle) -> AsyncIterator[dict]Events as the run makes them. A backend without a stream gives none.
| Parameter | Type | Default | Description |
|---|---|---|---|
handle |
RunHandle | required | The handle that start returned |
| returns | AsyncIterator[dict] | Each event as the run makes it |
Backend.run
async Backend.run(ctx: RunContext, agent: AgentSpec, run: RunSpec) -> RunResultStart a run and wait for its result; a cancel while it waits cancels the run, and goes on.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
RunContext | required | The run |
agent |
AgentSpec | required | The agent to run |
run |
RunSpec | required | The staged inputs and the run’s folders |
| returns | RunResult | What the run gave back |
class InProcessBackend
A backend whose agent runs in this process.
InProcessBackend.execute
async InProcessBackend.execute(ctx: RunContext, agent: AgentSpec, run: RunSpec) -> RunResultRun the agent, between sandbox_started and sandbox_completed, within the timeout in agent.limits.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
RunContext | required | The run, active while execute runs, so current_run gives it |
agent |
AgentSpec | required | The agent to run |
run |
RunSpec | required | The staged inputs and the run’s folders |
| returns | RunResult | What the agent gave back; the duration is set after |
InProcessBackend.start
async InProcessBackend.start(ctx: RunContext, agent: AgentSpec, run: RunSpec) -> RunHandleStart execute as an asyncio task, and return at once.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
RunContext | required | The run; its recorder takes sandbox_started and sandbox_completed |
agent |
AgentSpec | required | The agent to run |
run |
RunSpec | required | The staged inputs and the run’s folders |
| returns | RunHandle | The handle, which holds the task |
InProcessBackend.poll
async InProcessBackend.poll(handle: RunHandle) -> strTell how the task stands.
| Parameter | Type | Default | Description |
|---|---|---|---|
handle |
RunHandle | required | The handle that start returned |
| returns | str | “running”, “completed”, “failed” or “cancelled”, from the task |
InProcessBackend.result
async InProcessBackend.result(handle: RunHandle) -> RunResultWait for the task.
| Parameter | Type | Default | Description |
|---|---|---|---|
handle |
RunHandle | required | The handle that start returned |
| returns | RunResult | What execute returned; it raises what execute raised |
InProcessBackend.cancel
async InProcessBackend.cancel(handle: RunHandle) -> NoneCancel the task if it is going on, and wait for it to stop.
| Parameter | Type | Default | Description |
|---|---|---|---|
handle |
RunHandle | required | The handle that start returned |