research: pipeline-running signal + spinners so users aren't guessing
The prior flow was ambiguous: after hitting Start research, status flipped to "processing" and a "Submit for review" button appeared immediately with no indication that anything was actually running. Users had to guess whether the pipeline was working or stalled. Backend surfaces the truth as a signal: - new topology_runs::active_runs_for_research_topic counts queued+running runs whose research_topic_id matches - TopicDetail includes runs_in_flight: i64 alongside the existing status field, so the canvas can distinguish "pipeline still working" from "runner stalled". ResearchCanvas is now honest about state: - while runs_in_flight > 0, the header status pill grows a cyan "N runs in flight" badge with an inline SVG spinner - the stage-explainer card turns cyan-bordered and shows a "pipeline is running" hint, plus copy pointing the user at the Agents tier where each teammate's activity streams live - the "Submit for review (manual)" button is HIDDEN while any run is in flight — it's an escape hatch for stalled runs only, not the happy-path action. It reappears if runs_in_flight drops to zero but the topic is still marked processing, so a stalled runner can still be nudged along. - the canvas polls getTopic every 4s while status is processing/ publishing or runs_in_flight > 0, so the spinner + outcome swap in automatically when the pipeline completes. ResearchList sidebar: - each row's status dot becomes a spinner when the topic's status is processing or publishing, matching the canvas at a glance - the list also polls every 6s while ANY topic is active, so transitions land in the sidebar without waiting on a parent bump. The poll is gated on a derived boolean to avoid effect thrash. Follow-up: same pattern belongs on LoopsList / LoopsCanvas for loop iterations in flight — same signal (queued+running runs per loop) but not wired here.
This commit is contained in:
@@ -147,6 +147,26 @@ pub async fn enqueue_run_for_team(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Count `queued` + `running` runs whose `research_topic_id` matches. The
|
||||
/// research canvas polls this so it can show a spinner "the pipeline is
|
||||
/// running" and suppress the manual "Submit for review" escape hatch
|
||||
/// while any run is still in flight.
|
||||
pub async fn active_runs_for_research_topic(
|
||||
pool: &PgPool,
|
||||
research_topic_id: Uuid,
|
||||
) -> Result<i64, DbError> {
|
||||
let row = sqlx::query!(
|
||||
"SELECT count(*) AS n
|
||||
FROM topology_runs
|
||||
WHERE research_topic_id = $1
|
||||
AND status IN ('queued', 'running')",
|
||||
research_topic_id,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
Ok(row.n.unwrap_or(0))
|
||||
}
|
||||
|
||||
/// The research topic this run belongs to, if any. Used by the topology
|
||||
/// worker's `freeze_research_outcome` post-hook to snapshot the run's
|
||||
/// final synthesis into `research_outcomes`.
|
||||
|
||||
Reference in New Issue
Block a user