// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: task_cleanup.sql package db import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const clearTaskProcessCleanupPending = `-- name: ClearTaskProcessCleanupPending :exec UPDATE agent_task_queue SET result = result - 'process_cleanup_pending' WHERE id = $1 AND status IN ('cancelled', 'failed') AND result->>'process_cleanup_pending' = 'true' ` func (q *Queries) ClearTaskProcessCleanupPending(ctx context.Context, id pgtype.UUID) error { _, err := q.db.Exec(ctx, clearTaskProcessCleanupPending, id) return err } const failCancelledTaskProcessCleanup = `-- name: FailCancelledTaskProcessCleanup :one UPDATE agent_task_queue SET status = 'failed', error = concat_ws('; ', NULLIF(error, ''), $1::text), failure_reason = 'cleanup_unconfirmed', completed_at = now(), chat_finalize_deferred_at = NULL WHERE id = $2 AND status = 'cancelled' RETURNING id, agent_id, issue_id, status, priority, dispatched_at, started_at, completed_at, result, error, created_at, context, runtime_id, session_id, work_dir, trigger_comment_id, chat_session_id, autopilot_run_id, attempt, max_attempts, parent_task_id, failure_reason, trigger_summary, force_fresh_session, is_leader_task, wait_reason, initiator_user_id, handoff_note, prepare_lease_expires_at, squad_id, runtime_mcp_overlay, escalation_for_task_id, fire_at, originator_user_id, runtime_connected_apps, coalesced_comment_ids, delivered_comment_ids, chat_input_task_id, chat_finalize_deferred_at, originator_source, delegated_from_task_id, retry_of_task_id, rerun_of_task_id, rule_version_id, trigger_evidence_kind, trigger_evidence_ref_id, accountable_user_id, session_rollout_missing, retired_session_id, quick_actions_disabled, regenerate_quick_actions_for, branch_name, durable_work_dir, channel_context_revision, comment_thread_id, cancelled_by_type, cancelled_by_id, cancelled_by_name, issue_snapshot, workflow_step ` type FailCancelledTaskProcessCleanupParams struct { ErrorMessage string `json:"error_message"` ID pgtype.UUID `json:"id"` } // The daemon's cancellation acknowledgement can discover that local work did // NOT stop. Preserve the cancelled run's metadata but surface this as failure. // The status CAS makes replay harmless and leaves completed/failed rows alone. func (q *Queries) FailCancelledTaskProcessCleanup(ctx context.Context, arg FailCancelledTaskProcessCleanupParams) (AgentTaskQueue, error) { row := q.db.QueryRow(ctx, failCancelledTaskProcessCleanup, arg.ErrorMessage, arg.ID) var i AgentTaskQueue err := row.Scan( &i.ID, &i.AgentID, &i.IssueID, &i.Status, &i.Priority, &i.DispatchedAt, &i.StartedAt, &i.CompletedAt, &i.Result, &i.Error, &i.CreatedAt, &i.Context, &i.RuntimeID, &i.SessionID, &i.WorkDir, &i.TriggerCommentID, &i.ChatSessionID, &i.AutopilotRunID, &i.Attempt, &i.MaxAttempts, &i.ParentTaskID, &i.FailureReason, &i.TriggerSummary, &i.ForceFreshSession, &i.IsLeaderTask, &i.WaitReason, &i.InitiatorUserID, &i.HandoffNote, &i.PrepareLeaseExpiresAt, &i.SquadID, &i.RuntimeMcpOverlay, &i.EscalationForTaskID, &i.FireAt, &i.OriginatorUserID, &i.RuntimeConnectedApps, &i.CoalescedCommentIds, &i.DeliveredCommentIds, &i.ChatInputTaskID, &i.ChatFinalizeDeferredAt, &i.OriginatorSource, &i.DelegatedFromTaskID, &i.RetryOfTaskID, &i.RerunOfTaskID, &i.RuleVersionID, &i.TriggerEvidenceKind, &i.TriggerEvidenceRefID, &i.AccountableUserID, &i.SessionRolloutMissing, &i.RetiredSessionID, &i.QuickActionsDisabled, &i.RegenerateQuickActionsFor, &i.BranchName, &i.DurableWorkDir, &i.ChannelContextRevision, &i.CommentThreadID, &i.CancelledByType, &i.CancelledByID, &i.CancelledByName, &i.IssueSnapshot, &i.WorkflowStep, ) return i, err } const markPiTaskProcessCleanupPending = `-- name: MarkPiTaskProcessCleanupPending :exec UPDATE agent_task_queue task SET result = COALESCE(task.result, '{}'::jsonb) || '{"process_cleanup_pending":true}'::jsonb WHERE task.id = $1 AND task.status = 'cancelled' AND task.started_at IS NOT NULL AND task.result->>'process_cleanup_capability' = 'pi-process-cleanup-v1' AND EXISTS (SELECT 1 FROM agent_runtime runtime WHERE runtime.id = task.runtime_id AND runtime.provider IN ('pi', 'omp')) ` // Cancellation makes the task terminal before the daemon finishes stopping it. // Only a run that negotiated confirmation at start holds a fence until ack. func (q *Queries) MarkPiTaskProcessCleanupPending(ctx context.Context, id pgtype.UUID) error { _, err := q.db.Exec(ctx, markPiTaskProcessCleanupPending, id) return err } const taskBlockedByProcessCleanup = `-- name: TaskBlockedByProcessCleanup :one SELECT EXISTS ( SELECT 1 FROM agent_task_queue candidate JOIN LATERAL ( SELECT CASE WHEN unsafe.status = 'cancelled' AND unsafe.result->>'process_cleanup_pending' = 'true' THEN unsafe.completed_at + interval '30 seconds' ELSE COALESCE(unsafe.completed_at, unsafe.created_at) END AS completed_at FROM agent_task_queue unsafe WHERE unsafe.agent_id = candidate.agent_id AND unsafe.runtime_id = candidate.runtime_id AND (unsafe.failure_reason = 'cleanup_unconfirmed' OR (unsafe.status = 'cancelled' AND unsafe.result->>'process_cleanup_pending' = 'true' AND unsafe.completed_at <= now() - interval '30 seconds')) ORDER BY unsafe.completed_at DESC, unsafe.id DESC LIMIT 1 ) unsafe ON true WHERE candidate.id = $1 AND candidate.status IN ('queued', 'dispatched', 'waiting_local_directory') AND NOT EXISTS ( SELECT 1 FROM agent_task_queue manual WHERE manual.agent_id = candidate.agent_id AND manual.runtime_id = candidate.runtime_id AND manual.rerun_of_task_id IS NOT NULL AND manual.retry_of_task_id IS NULL AND manual.created_at > unsafe.completed_at AND (manual.id = candidate.id OR manual.status = 'completed') ) ) ` // A cleanup failure fences this agent on this runtime, including already queued // work and future scheduled runs. Only a NEW explicit manual rerun can cross // the fence; its successful completion allows later automated work again. // Existing failure and result fields are the durable safety markers. func (q *Queries) TaskBlockedByProcessCleanup(ctx context.Context, taskID pgtype.UUID) (bool, error) { row := q.db.QueryRow(ctx, taskBlockedByProcessCleanup, taskID) var exists bool err := row.Scan(&exists) return exists, err } const taskWaitingForProcessCleanup = `-- name: TaskWaitingForProcessCleanup :one SELECT EXISTS ( SELECT 1 FROM agent_task_queue candidate JOIN agent_task_queue stopping ON stopping.agent_id = candidate.agent_id AND stopping.runtime_id = candidate.runtime_id WHERE candidate.id = $1 AND candidate.status IN ('dispatched', 'waiting_local_directory') AND stopping.status = 'cancelled' AND stopping.result->>'process_cleanup_pending' = 'true' AND stopping.completed_at > now() - interval '30 seconds' ) ` func (q *Queries) TaskWaitingForProcessCleanup(ctx context.Context, id pgtype.UUID) (bool, error) { row := q.db.QueryRow(ctx, taskWaitingForProcessCleanup, id) var exists bool err := row.Scan(&exists) return exists, err }