Agent pairs a configured harness and model with a Runtime, configured through AgentConfig. Calling agent.run(task) executes a full rollout on a Task and returns its Trace:
agent.interaction(task) holds the rollout open as an async context manager. The caller acts as the user, and each call to turn() runs one harness segment (which may span several model and tool calls) and returns a Segment. If the task already defines a prompt, call turn() with no arguments to run the opening turn; if prompt=None, pass the first user message to turn(message).
You can keep sending follow-up messages until segment.terminated is true (subsequent calls after termination return an empty terminated segment without consuming the message), or exit the async with block early to end the exchange yourself. Leaving the block finalizes and scores the rollout so interaction.trace is ready to inspect:
Messages during an active turn
turn() is designed for sequential exchanges where each user message waits for the previous segment to finish. When you need to send input while the agent is still working, or wake an idle interaction with new input, use interaction.send():
mode="steer"(the default) injects the message at the harness’s next safe point during active work, which requires a harness that supports live steering.mode="queue"holds the message until the current turn yields, then delivers any pending messages together in order at the start of the next turn. Because it waits for a turn boundary rather than interrupting an active tool or model call, it does not require steering support.
prompt, start the opening turn() before calling send(). Note that the returned receipt confirms whether the message was accepted for delivery, not that the agent has finished acting on it. Keep the interaction context open while the agent works, since exiting the block cancels outstanding deliveries and finishes the rollout.
Verification placement
agent.scoring.mode selects whether task scoring runs in the agent’s workspace (shared) or in a fresh container (isolated). Tasks can declare their own defaults on TaskData.scoring via ScoringConfig, and any fields explicitly set on agent.scoring override the task defaults (falling back to shared when neither sets a mode).
When mode="isolated", verifiers restores the task’s collected artifacts into a fresh runtime before running task metrics, rewards, and judge plugins:
agent.scoring.runtimeoptionally overrides the runtime configuration used for the isolated verifier.agent.scoring.envmerges overTaskData.scoring.envin bothsharedandisolatedmodes, resolving${VAR}and${VAR:-default}templates from the host environment when scoring starts.agent.scoring.networksets the task’s network policy while scoring runs, replacingTaskData.scoring.network; see network policies.agent.scoring.retriesconfiguresRetryConfigfor isolated scoring (defaulting tomax_retries = 2), reusing the completed submission in a fresh scoring environment whenever a retryable error occurs. Shared scoring is not retried.
Skip scoring for cut-off runs
A truncated or timed-out run is often not worth grading. Setagent.scoring.skip_on_truncated to skip task scoring when Trace.is_truncated is true (a turn or token cap, or a length-finished response). Set agent.scoring.skip_on_timeout to skip it when a stage deadline expired before scoring (Trace.is_timeout). A skipped trace keeps no task rewards, metrics, or judge scores, so its reward is 0. trace.info["scoring_skipped"] records the reason ("truncated" or "timeout"). Task finalization and harness metrics still run.
Trace.is_truncated only checks the run’s last model response. Some harnesses keep going after a response hits its per-turn token cap: they compact, or answer a cut-off tool call. Set agent.max_turn_tokens to cap each response and stop the run before the next model call once a response hits that cap. The stop condition is max_turn_tokens. The run is then truncated, so skip_on_truncated applies.