mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-07 08:27:12 +00:00
parent
0d60bc6e04
commit
e0fdf0f04d
4 changed files with 517 additions and 111 deletions
468
run.json
468
run.json
File diff suppressed because one or more lines are too long
149
stages/007-simplify_gpt@1/diff.patch
Normal file
149
stages/007-simplify_gpt@1/diff.patch
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
diff --git a/lib/crates/fabro-store/src/run_state.rs b/lib/crates/fabro-store/src/run_state.rs
|
||||
index 304acf8cc..72105abdd 100644
|
||||
--- a/lib/crates/fabro-store/src/run_state.rs
|
||||
+++ b/lib/crates/fabro-store/src/run_state.rs
|
||||
@@ -949,9 +949,9 @@ mod tests {
|
||||
AgentAcpCancelledProps, AgentAcpCompletedProps, AgentAcpStartedProps,
|
||||
AgentAcpTimedOutProps, AgentMessageProps, AgentSessionActivatedProps,
|
||||
AgentSessionEndedProps, AgentSessionStartedProps, CheckpointCompletedProps,
|
||||
- InterviewCompletedProps, InterviewOption, InterviewStartedProps, RunControlEffectProps,
|
||||
- StageCompletedProps, StageFailedProps, StagePromptProps, StageRetryingProps,
|
||||
- StageStartedProps,
|
||||
+ InterviewCompletedProps, InterviewOption, InterviewStartedProps, RunCompletedProps,
|
||||
+ RunControlEffectProps, StageCompletedProps, StageFailedProps, StagePromptProps,
|
||||
+ StageRetryingProps, StageStartedProps,
|
||||
};
|
||||
use fabro_types::{
|
||||
AgentBackend, BilledModelUsage, BilledTokenCounts, BlockedReason, Checkpoint,
|
||||
@@ -1127,6 +1127,81 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
+ #[test]
|
||||
+ fn live_run_timing_matches_conclusion_timing_at_conclusion_moment() {
|
||||
+ let mut state = initialized_projection();
|
||||
+ let started_at = test_dt("2026-04-07T12:00:00Z");
|
||||
+ let completed_at = test_dt("2026-04-07T12:00:10Z");
|
||||
+ state
|
||||
+ .apply_event(&test_raw_event_at(
|
||||
+ 1,
|
||||
+ "2026-04-07T12:00:00Z",
|
||||
+ "run.started",
|
||||
+ &json!({ "name": "Test run" }),
|
||||
+ None,
|
||||
+ ))
|
||||
+ .unwrap();
|
||||
+ state
|
||||
+ .apply_event(&test_raw_event_at(
|
||||
+ 2,
|
||||
+ "2026-04-07T12:00:00Z",
|
||||
+ "run.starting",
|
||||
+ &json!({}),
|
||||
+ None,
|
||||
+ ))
|
||||
+ .unwrap();
|
||||
+ state
|
||||
+ .apply_event(&test_raw_event_at(
|
||||
+ 3,
|
||||
+ "2026-04-07T12:00:01Z",
|
||||
+ "run.running",
|
||||
+ &json!({}),
|
||||
+ None,
|
||||
+ ))
|
||||
+ .unwrap();
|
||||
+ state.stage_entry("plan", 1, first_event_seq(4)).timing =
|
||||
+ Some(fabro_types::StageTiming::new(2_000, 700, 300));
|
||||
+ state.stage_entry("code", 1, first_event_seq(5)).timing =
|
||||
+ Some(fabro_types::StageTiming::new(3_000, 50, 200));
|
||||
+
|
||||
+ let conclusion_timing = fabro_types::RunTiming::new(
|
||||
+ u64::try_from(
|
||||
+ completed_at
|
||||
+ .signed_duration_since(started_at)
|
||||
+ .num_milliseconds(),
|
||||
+ )
|
||||
+ .unwrap(),
|
||||
+ 750,
|
||||
+ 500,
|
||||
+ );
|
||||
+ let mut completed = test_event(
|
||||
+ 6,
|
||||
+ EventBody::RunCompleted(RunCompletedProps {
|
||||
+ timing: conclusion_timing,
|
||||
+ artifact_count: 0,
|
||||
+ status: "succeeded".to_string(),
|
||||
+ reason: SuccessReason::Completed,
|
||||
+ total_usd_micros: None,
|
||||
+ final_git_commit_sha: None,
|
||||
+ final_patch: None,
|
||||
+ diff_summary: None,
|
||||
+ billing: None,
|
||||
+ }),
|
||||
+ None,
|
||||
+ );
|
||||
+ completed.event.ts = completed_at;
|
||||
+ state.apply_event(&completed).unwrap();
|
||||
+
|
||||
+ assert_eq!(
|
||||
+ state
|
||||
+ .conclusion
|
||||
+ .as_ref()
|
||||
+ .map(|conclusion| conclusion.timing),
|
||||
+ Some(conclusion_timing)
|
||||
+ );
|
||||
+ assert_eq!(state.live_run_timing(completed_at), Some(conclusion_timing));
|
||||
+ }
|
||||
+
|
||||
#[test]
|
||||
fn last_event_at_tracks_most_recent_event_timestamp() {
|
||||
let mut state = initialized_projection();
|
||||
diff --git a/lib/crates/fabro-store/src/slate/projection_cache.rs b/lib/crates/fabro-store/src/slate/projection_cache.rs
|
||||
index 9e4f41a34..aa4974c2f 100644
|
||||
--- a/lib/crates/fabro-store/src/slate/projection_cache.rs
|
||||
+++ b/lib/crates/fabro-store/src/slate/projection_cache.rs
|
||||
@@ -96,9 +96,10 @@ impl RunProjectionCacheState {
|
||||
/// Apply read-time overlays to a cached entry. Pure: does not touch the cache
|
||||
/// state, so it can run outside the cache mutex.
|
||||
fn apply_read_overlays(entry: &mut CachedRunProjection, now: DateTime<Utc>) {
|
||||
- // `Conclusion::timing` is the authoritative terminal snapshot; only fill
|
||||
- // in a derived live timing for runs that have not yet concluded.
|
||||
- if entry.projection.conclusion.is_none() {
|
||||
+ // `Conclusion::timing` is the authoritative terminal snapshot and is
|
||||
+ // already present in cached terminal summaries. Only fill missing timing
|
||||
+ // with the best-effort live projection.
|
||||
+ if entry.summary.timing.is_none() {
|
||||
entry.summary.timing = entry.projection.live_run_timing(now);
|
||||
}
|
||||
}
|
||||
@@ -117,7 +118,7 @@ impl RunProjectionCache {
|
||||
query: &ListRunsQuery,
|
||||
now: DateTime<Utc>,
|
||||
) -> Vec<CachedRunProjection> {
|
||||
- let mut entries = {
|
||||
+ let entries = {
|
||||
let state = self.state.lock().await;
|
||||
let raw = match query.parent_id {
|
||||
Some(parent_id) => state
|
||||
@@ -133,10 +134,6 @@ impl RunProjectionCache {
|
||||
.map(|entry| state.with_children_count(entry))
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
- // Apply per-entry live overlays outside the cache mutex.
|
||||
- for entry in &mut entries {
|
||||
- apply_read_overlays(entry, now);
|
||||
- }
|
||||
let mut entries = entries
|
||||
.into_iter()
|
||||
.filter(|entry| {
|
||||
@@ -150,6 +147,11 @@ impl RunProjectionCache {
|
||||
true
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
+ // Apply per-entry live overlays outside the cache mutex, after any
|
||||
+ // date filtering so skipped entries do not sum stage timings.
|
||||
+ for entry in &mut entries {
|
||||
+ apply_read_overlays(entry, now);
|
||||
+ }
|
||||
entries.sort_by(|left, right| {
|
||||
right
|
||||
.run_id
|
||||
6
stages/007-simplify_gpt@1/status.json
Normal file
6
stages/007-simplify_gpt@1/status.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"outcome": "succeeded",
|
||||
"notes": "Stage completed: simplify_gpt",
|
||||
"failure_reason": null,
|
||||
"timestamp": "2026-05-23T10:35:39.112641Z"
|
||||
}
|
||||
5
stages/008-verify@1/script_invocation.json
Normal file
5
stages/008-verify@1/script_invocation.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"script": "cargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --cargo-quiet --workspace --status-level fail 2>&1 && cargo dev docs refresh 2>&1 && cargo dev docs check 2>&1",
|
||||
"command": "exec 2>&1\ncargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --cargo-quiet --workspace --status-level fail 2>&1 && cargo dev docs refresh 2>&1 && cargo dev docs check 2>&1",
|
||||
"language": "shell"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue