mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-11 20:27:44 +02:00
[aidan] fix/run-status: sync ongoing runs and heal stuck/interrupted runs
This commit is contained in:
@@ -215,6 +215,19 @@ async def execute(
|
||||
"last_run_id": run.id,
|
||||
})
|
||||
|
||||
# Announce the run as running the instant it claims execution, not at the
|
||||
# first step. Without this a run that fails fast (e.g. no runnable steps) or
|
||||
# hasn't streamed yet never hits the Home "Ongoing runs" list, so a batch of
|
||||
# missed re-runs only ever surfaced whichever one reached its first step.
|
||||
try:
|
||||
from backend.apps.agents.core.ws_manager import ws_manager as _wsm_start
|
||||
await _wsm_start.broadcast_global("workflow:run", {
|
||||
"workflow_id": wf.id,
|
||||
"run": run.model_dump(mode="json"),
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
session = None
|
||||
try:
|
||||
steps = [s for s in wf.steps if s.enabled and s.text and s.text.strip()]
|
||||
|
||||
@@ -362,6 +362,14 @@ def _mark_stuck_runs_failed() -> None:
|
||||
error="OpenSwarm closed before this run finished.",
|
||||
finished_at=now,
|
||||
)
|
||||
# The run row is fixed, but the workflow still summarizes this
|
||||
# dead run as 'running' (that's what the detail header reads), so
|
||||
# heal the summary too when this was the latest run.
|
||||
if wf.last_run_id == r.id and wf.last_run_status == "running":
|
||||
executor._persist_run_fields(wf, {
|
||||
"last_run_status": "failure",
|
||||
"last_run_at": now,
|
||||
})
|
||||
|
||||
|
||||
def record_skipped(wf: Workflow, scheduled_for: datetime, error: str) -> WorkflowRun:
|
||||
|
||||
@@ -230,6 +230,17 @@ function mergeRunIntoState(state: State, r: WorkflowRun) {
|
||||
wf.last_run_status = r.status === 'skipped' ? wf.last_run_status : (r.status as Workflow['last_run_status']);
|
||||
wf.last_run_id = r.id;
|
||||
}
|
||||
// Keep the live "Ongoing runs" list in sync off the WS stream: a run that's no
|
||||
// longer running drops out of `active`, a freshly-running one joins. Without
|
||||
// this, `active` only refreshed on the one-shot mount fetch, so finished runs
|
||||
// lingered as "Working…" while the monitor already showed them done.
|
||||
const activeIdx = state.active.findIndex((a) => a.run_id === r.id);
|
||||
if (r.status === 'running') {
|
||||
const entry: ActiveRun = { workflow_id: r.workflow_id, run_id: r.id, title: wf?.title || '', started_at: r.started_at };
|
||||
if (activeIdx >= 0) state.active[activeIdx] = entry; else state.active.unshift(entry);
|
||||
} else if (activeIdx >= 0) {
|
||||
state.active.splice(activeIdx, 1);
|
||||
}
|
||||
// Auto-flip the card view on run state transitions so the user sees
|
||||
// Running while it streams, Completed on success, Failed on failure.
|
||||
// Only nudge from views that the user hasn't actively navigated away
|
||||
|
||||
Reference in New Issue
Block a user