mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-09-01 00:59:33 +00:00
feat(web): DB-backed Jobs tab + scheduler-dispatched local jobs (#436)
* feat(web): DB-backed Jobs tab, scheduler-dispatched local jobs, remove active-jobs-bar - Remove active-jobs-bar UI element (HTML, CSS, JS polling) - Move job handlers from server.rs to handlers/jobs.rs - Remove user_id scoping (single-user gateway) - Add list_agent_jobs() and agent_job_summary() to Database trait (both postgres and libsql backends) for non-sandbox job visibility - Wire SchedulerSlot into CreateJobTool so execute_local dispatches via scheduler (persists to DB + spawns worker) instead of creating phantom ContextManager-only jobs - Update /status and /list slash commands to read from DB for consistency with Jobs tab - Fix worker mark_completed: skip if already terminal or stuck - Add agent job cancel via DB update in both web handler and slash cmd - Add Stuck → Completed guard with tracing in worker completion path Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix: address PR review comments - Log warning when get_context fails in worker completion path - Extract duplicated status-counting logic into AgentJobSummary::add_count() helper, used by both postgres and libsql backends Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --------- Co-authored-by: Claude Sonnet 4.6 <[email protected]> Co-authored-by: Nick Pismenkov <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
Nick Pismenkov
parent
afb49597ac
commit
6481448d50
@@ -158,6 +158,37 @@ Report when the job is complete or if you encounter issues you cannot resolve."#
|
||||
match result {
|
||||
Ok(Ok(())) => {
|
||||
tracing::info!("Worker for job {} completed successfully", self.job_id);
|
||||
// Only mark completed if still in an active, non-stuck state.
|
||||
// The execution_loop may have already called mark_completed or
|
||||
// mark_stuck (e.g. "plan completed but work remains").
|
||||
let current_state = self
|
||||
.context_manager()
|
||||
.get_context(self.job_id)
|
||||
.await
|
||||
.map(|ctx| ctx.state);
|
||||
match current_state {
|
||||
Ok(state) if state.is_terminal() => {
|
||||
// Already in a terminal state (e.g. execution_loop
|
||||
// called mark_completed itself).
|
||||
}
|
||||
Ok(JobState::Stuck) => {
|
||||
// execution_loop marked this as stuck (e.g. "plan
|
||||
// completed but work remains"); leave for self-repair.
|
||||
tracing::info!(
|
||||
"Job {} returned Ok but is Stuck — leaving for self-repair",
|
||||
self.job_id
|
||||
);
|
||||
}
|
||||
Ok(_) => {
|
||||
self.mark_completed().await?;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
job_id = %self.job_id,
|
||||
"Failed to get job context, cannot mark as completed: {}", e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
tracing::error!("Worker for job {} failed: {}", self.job_id, e);
|
||||
|
||||
Reference in New Issue
Block a user