pub struct RunSummary {
pub run_id: i64,
pub outcome: String,
pub success: bool,
pub steps: u32,
pub tokens: u64,
pub duration_ms: Option<u64>,
pub finished_at: String,
}Expand description
What one finished run cost and whether it worked.
Written once by Store::finish_run and read back with
Store::run_summary. Before 0.12.0 a consumer had to assemble this itself
from three different queries plus knowledge of which of eleven outcome
strings count as success — and could not get duration_ms at all, because
nothing recorded when a run ended.
Serialisable, so a scoring tool can store or ship it without restating the shape.
use io_harness::{Store, StepRecord};
let store = Store::memory()?;
let run_id = store.start_run("add a hello function", "src/hello.rs")?;
store.record(run_id, &StepRecord::new(1, "wrote src/hello.rs", "ok").with_trace("", "", 1_280))?;
store.finish_run(run_id, "step_cap_reached")?;
// One row instead of three queries plus knowledge of which of eleven outcome
// strings mean success. This is what a scoring tool reads per run.
let summary = store.run_summary(run_id)?.expect("the run has finished");
assert!(!summary.success);
// `outcome` and `success` are both kept on purpose: the flag says whether it
// worked, the string says *how* it ended, and a step cap, a stall and a
// human's refusal are three different things to act on.
assert_eq!(summary.outcome, "step_cap_reached");
assert_eq!((summary.steps, summary.tokens), (1, 1_280));
// `None` while a run is unfinished or paused for a human — absent rather than
// a row of zeroes, which would read like a run that did nothing.
let paused = store.start_run("rewrite the changelog", "CHANGELOG.md")?;
store.finish_run(paused, "awaiting_approval")?;
assert!(store.run_summary(paused)?.is_none());Fields§
§run_id: i64The run this describes.
outcome: StringThe raw outcome string, as written to runs.outcome.
Kept alongside Self::success rather than replaced by it: the string
says which ending, the flag says whether it was the good one, and
collapsing them would throw away the distinction between a step cap, a
stall and a human’s refusal.
success: boolWhether the run achieved what it was asked to do.
True for exactly one outcome — success. Every other ending, including
the ones that are nobody’s fault like a rate-limited provider, is not the
task being done.
steps: u32Steps completed, as MAX(step).
Not COUNT(*) over steps: a retry writes its own row under the same
step number, so counting rows counts trace entries rather than agent
steps. For a tree this is the ROOT agent’s step count, not the tree’s
total — each agent has its own summary.
tokens: u64Tokens spent by this run, summed from its committed steps.
Tokens, not money. A provider reports usage and never a price, so the
crate has nothing to convert with; see
Containment::max_total_cost.
duration_ms: Option<u64>Wall-clock milliseconds from the run’s start to its end.
None for a run started before 0.7.0, which has no started_at to
measure from. Includes time the process was not running — a run that
crashed at midnight and resumed at nine counts the nine hours, because
that is how long the run took even though it was not working.
finished_at: StringWhen the run ended, from the database clock.
Trait Implementations§
Source§impl Clone for RunSummary
impl Clone for RunSummary
Source§fn clone(&self) -> RunSummary
fn clone(&self) -> RunSummary
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for RunSummary
impl Debug for RunSummary
Source§impl<'de> Deserialize<'de> for RunSummary
impl<'de> Deserialize<'de> for RunSummary
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for RunSummary
Source§impl PartialEq for RunSummary
impl PartialEq for RunSummary
Source§impl Serialize for RunSummary
impl Serialize for RunSummary
impl StructuralPartialEq for RunSummary
Auto Trait Implementations§
impl Freeze for RunSummary
impl RefUnwindSafe for RunSummary
impl Send for RunSummary
impl Sync for RunSummary
impl Unpin for RunSummary
impl UnsafeUnpin for RunSummary
impl UnwindSafe for RunSummary
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.