Files
multica/server/pkg/db/generated/wakeup.sql.go
T
Bohan Jiangandmultica-agent bd70632999 fix(wakeup): end closed-issue wakeups in the application, not a trigger (MUL-7557) (#8642)
Migration 518/520 (#8467) registered stop_issue_wakeups, an AFTER UPDATE
OF status trigger on issue that disabled issue_wakeup rows and cancelled
queued/deferred wakeup runs in agent_task_queue. That is a database-level
cascading update, which the repository's migration rules forbid.

Drop the trigger and function (migration 533) and apply the same close rule
in the transaction that writes the status: single and batch issue updates
and the merged-PR auto-close. Cancelled runs are now broadcast after commit.

Co-authored-by: multica-agent <[email protected]>
2026-09-21 18:04:26 +08:00

1261 lines
44 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: wakeup.sql
package db
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const advanceIssueWakeup = `-- name: AdvanceIssueWakeup :exec
UPDATE issue_wakeup SET enabled= $1,next_fire_at=$2,last_task_id=COALESCE($3,last_task_id),last_error=$4,updated_at=clock_timestamp() WHERE id= $5
`
type AdvanceIssueWakeupParams struct {
Enabled bool `json:"enabled"`
NextFireAt pgtype.Timestamptz `json:"next_fire_at"`
LastTaskID pgtype.UUID `json:"last_task_id"`
LastError pgtype.Text `json:"last_error"`
ID pgtype.UUID `json:"id"`
}
func (q *Queries) AdvanceIssueWakeup(ctx context.Context, arg AdvanceIssueWakeupParams) error {
_, err := q.db.Exec(ctx, advanceIssueWakeup,
arg.Enabled,
arg.NextFireAt,
arg.LastTaskID,
arg.LastError,
arg.ID,
)
return err
}
const cancelUnstartedIssueWakeupTasks = `-- name: CancelUnstartedIssueWakeupTasks :many
UPDATE agent_task_queue SET status='cancelled',completed_at=now(),error='Issue closed; wakeup disabled'
WHERE issue_id= $1 AND context->>'wakeup_id' IS NOT NULL AND status IN ('queued','deferred') AND started_at IS NULL 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
`
func (q *Queries) CancelUnstartedIssueWakeupTasks(ctx context.Context, issueID pgtype.UUID) ([]AgentTaskQueue, error) {
rows, err := q.db.Query(ctx, cancelUnstartedIssueWakeupTasks, issueID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentTaskQueue{}
for rows.Next() {
var i AgentTaskQueue
if err := rows.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,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const cancelUnstartedWakeupTasks = `-- name: CancelUnstartedWakeupTasks :many
UPDATE agent_task_queue SET status='cancelled',completed_at=now(),error='Wakeup disabled or updated'
WHERE context->>'wakeup_id'= $1::text AND status IN ('queued','deferred') AND started_at IS NULL 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
`
func (q *Queries) CancelUnstartedWakeupTasks(ctx context.Context, wakeupID string) ([]AgentTaskQueue, error) {
rows, err := q.db.Query(ctx, cancelUnstartedWakeupTasks, wakeupID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentTaskQueue{}
for rows.Next() {
var i AgentTaskQueue
if err := rows.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,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const consumeWakeupReceipts = `-- name: ConsumeWakeupReceipts :exec
UPDATE issue_wakeup_receipt SET task_id=$1,processed_at=now() WHERE id=ANY($2::uuid[])
`
type ConsumeWakeupReceiptsParams struct {
TaskID pgtype.UUID `json:"task_id"`
Ids []pgtype.UUID `json:"ids"`
}
func (q *Queries) ConsumeWakeupReceipts(ctx context.Context, arg ConsumeWakeupReceiptsParams) error {
_, err := q.db.Exec(ctx, consumeWakeupReceipts, arg.TaskID, arg.Ids)
return err
}
const createIssueWakeup = `-- name: CreateIssueWakeup :one
INSERT INTO issue_wakeup(id,workspace_id,issue_id,agent_id,created_by,source_task_id,parent_comment_id,instruction,kind,mode,event_types,filter_agent_id,filter_task_id,filter_actor_type,filter_actor_id,interval_seconds,cron_expression,timezone,next_fire_at)
VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19) RETURNING id, workspace_id, issue_id, agent_id, created_by, source_task_id, parent_comment_id, instruction, kind, mode, event_types, filter_agent_id, filter_task_id, interval_seconds, cron_expression, timezone, next_fire_at, enabled, disabled_at, revision, last_task_id, last_error, created_at, updated_at, filter_actor_type, filter_actor_id
`
type CreateIssueWakeupParams struct {
ID pgtype.UUID `json:"id"`
WorkspaceID pgtype.UUID `json:"workspace_id"`
IssueID pgtype.UUID `json:"issue_id"`
AgentID pgtype.UUID `json:"agent_id"`
CreatedBy pgtype.UUID `json:"created_by"`
SourceTaskID pgtype.UUID `json:"source_task_id"`
ParentCommentID pgtype.UUID `json:"parent_comment_id"`
Instruction string `json:"instruction"`
Kind string `json:"kind"`
Mode string `json:"mode"`
EventTypes []string `json:"event_types"`
FilterAgentID pgtype.UUID `json:"filter_agent_id"`
FilterTaskID pgtype.UUID `json:"filter_task_id"`
FilterActorType pgtype.Text `json:"filter_actor_type"`
FilterActorID pgtype.UUID `json:"filter_actor_id"`
IntervalSeconds pgtype.Int8 `json:"interval_seconds"`
CronExpression pgtype.Text `json:"cron_expression"`
Timezone string `json:"timezone"`
NextFireAt pgtype.Timestamptz `json:"next_fire_at"`
}
func (q *Queries) CreateIssueWakeup(ctx context.Context, arg CreateIssueWakeupParams) (IssueWakeup, error) {
row := q.db.QueryRow(ctx, createIssueWakeup,
arg.ID,
arg.WorkspaceID,
arg.IssueID,
arg.AgentID,
arg.CreatedBy,
arg.SourceTaskID,
arg.ParentCommentID,
arg.Instruction,
arg.Kind,
arg.Mode,
arg.EventTypes,
arg.FilterAgentID,
arg.FilterTaskID,
arg.FilterActorType,
arg.FilterActorID,
arg.IntervalSeconds,
arg.CronExpression,
arg.Timezone,
arg.NextFireAt,
)
var i IssueWakeup
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.IssueID,
&i.AgentID,
&i.CreatedBy,
&i.SourceTaskID,
&i.ParentCommentID,
&i.Instruction,
&i.Kind,
&i.Mode,
&i.EventTypes,
&i.FilterAgentID,
&i.FilterTaskID,
&i.IntervalSeconds,
&i.CronExpression,
&i.Timezone,
&i.NextFireAt,
&i.Enabled,
&i.DisabledAt,
&i.Revision,
&i.LastTaskID,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.FilterActorType,
&i.FilterActorID,
)
return i, err
}
const createWakeupTask = `-- name: CreateWakeupTask :one
INSERT INTO agent_task_queue (
agent_id, runtime_id, issue_id, status, priority, trigger_comment_id,
coalesced_comment_ids, trigger_summary, force_fresh_session, is_leader_task, handoff_note,
squad_id, context, originator_user_id, accountable_user_id, runtime_mcp_overlay, runtime_connected_apps,
originator_source, delegated_from_task_id, rule_version_id, rerun_of_task_id, trigger_evidence_kind, trigger_evidence_ref_id,
id
)
SELECT
$1, $2, $3, 'queued', $4, $5,
COALESCE($6::uuid[], '{}'),
$7,
COALESCE($8::boolean, FALSE),
COALESCE($9::boolean, FALSE),
$10,
$11,
CASE
WHEN COALESCE($12::text, '') <> ''
THEN jsonb_build_object('head_sha', $12::text)
ELSE '{}'::jsonb
END || $13::jsonb,
$14,
$15,
$16,
$17,
$18,
$19,
$20,
$21,
$22,
$23,
COALESCE($24::uuid, gen_random_uuid())
WHERE lock_task_owner_rows($1, $3, $2)
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
`
type CreateWakeupTaskParams struct {
AgentID pgtype.UUID `json:"agent_id"`
RuntimeID pgtype.UUID `json:"runtime_id"`
IssueID pgtype.UUID `json:"issue_id"`
Priority int32 `json:"priority"`
TriggerCommentID pgtype.UUID `json:"trigger_comment_id"`
CoalescedCommentIds []pgtype.UUID `json:"coalesced_comment_ids"`
TriggerSummary pgtype.Text `json:"trigger_summary"`
ForceFreshSession pgtype.Bool `json:"force_fresh_session"`
IsLeaderTask pgtype.Bool `json:"is_leader_task"`
HandoffNote pgtype.Text `json:"handoff_note"`
SquadID pgtype.UUID `json:"squad_id"`
HeadSha pgtype.Text `json:"head_sha"`
WakeupContext []byte `json:"wakeup_context"`
OriginatorUserID pgtype.UUID `json:"originator_user_id"`
AccountableUserID pgtype.UUID `json:"accountable_user_id"`
RuntimeMcpOverlay []byte `json:"runtime_mcp_overlay"`
RuntimeConnectedApps []byte `json:"runtime_connected_apps"`
OriginatorSource pgtype.Text `json:"originator_source"`
DelegatedFromTaskID pgtype.UUID `json:"delegated_from_task_id"`
RuleVersionID pgtype.UUID `json:"rule_version_id"`
RerunOfTaskID pgtype.UUID `json:"rerun_of_task_id"`
TriggerEvidenceKind pgtype.Text `json:"trigger_evidence_kind"`
TriggerEvidenceRefID pgtype.UUID `json:"trigger_evidence_ref_id"`
ID pgtype.UUID `json:"id"`
}
// Fenced against workspace teardown: lock_task_owner_rows (migration 284)
// locks the owners' workspace rows in the writer's own transaction and returns
// false once they are gone, so this statement writes no row instead of stranding
// a task in a workspace that has just been deleted (MUL-5999).
// head_sha stamps the commit under review into the task's context JSONB so the
// reviewer-loop dedup (HasPendingTaskForIssueAndAgent) can tell a pending run
// against an OLD head apart from a fresh request against a NEW head (TEN-356).
// Empty/absent head_sha leaves context NULL, preserving pre-TEN-356 behavior for
// issues with no linked PR. Issue-linked tasks never hit quick-create context
// parsing (parseQuickCreateContext short-circuits on IssueID.Valid), so this
// key rides harmlessly alongside.
// id is minted by the application as a UUIDv7 (pkg/dbid) so consecutive
// enqueues cluster in a narrow contiguous primary-key range instead of
// scattering across the B-tree. On a table with existing v4 ids, that range
// is not necessarily the tree's right edge.
// COALESCE keeps the column's gen_random_uuid() default reachable, so a caller
// that passes no id still inserts — it just gets a random v4, exactly as before.
// The same pattern is used by every INSERT listed in pkg/dbid's write table.
func (q *Queries) CreateWakeupTask(ctx context.Context, arg CreateWakeupTaskParams) (AgentTaskQueue, error) {
row := q.db.QueryRow(ctx, createWakeupTask,
arg.AgentID,
arg.RuntimeID,
arg.IssueID,
arg.Priority,
arg.TriggerCommentID,
arg.CoalescedCommentIds,
arg.TriggerSummary,
arg.ForceFreshSession,
arg.IsLeaderTask,
arg.HandoffNote,
arg.SquadID,
arg.HeadSha,
arg.WakeupContext,
arg.OriginatorUserID,
arg.AccountableUserID,
arg.RuntimeMcpOverlay,
arg.RuntimeConnectedApps,
arg.OriginatorSource,
arg.DelegatedFromTaskID,
arg.RuleVersionID,
arg.RerunOfTaskID,
arg.TriggerEvidenceKind,
arg.TriggerEvidenceRefID,
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,
)
return i, err
}
const deleteExpiredWakeupReceipts = `-- name: DeleteExpiredWakeupReceipts :execrows
WITH batch AS MATERIALIZED (
SELECT expired.id FROM issue_wakeup_receipt expired WHERE expired.processed_at < $1
ORDER BY expired.processed_at,expired.id LIMIT 1000 FOR UPDATE SKIP LOCKED
)
DELETE FROM issue_wakeup_receipt r USING batch WHERE r.id=batch.id
`
// Pending inputs are never expired. Bound work and avoid waiting on dispatch.
// MATERIALIZED evaluates the batch once. As an IN subquery, a nested-loop plan
// rescans it per outer row, skips the rows this DELETE already removed, and
// slides the LIMIT window until every expired row is gone.
func (q *Queries) DeleteExpiredWakeupReceipts(ctx context.Context, cutoff pgtype.Timestamptz) (int64, error) {
result, err := q.db.Exec(ctx, deleteExpiredWakeupReceipts, cutoff)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const disableIssueWakeups = `-- name: DisableIssueWakeups :exec
UPDATE issue_wakeup SET enabled=false,disabled_at=clock_timestamp(),updated_at=clock_timestamp()
WHERE issue_id= $1 AND disabled_at IS NULL
`
// Closing wins over every subscription on the issue; reopening does not rearm.
func (q *Queries) DisableIssueWakeups(ctx context.Context, issueID pgtype.UUID) error {
_, err := q.db.Exec(ctx, disableIssueWakeups, issueID)
return err
}
const discardWakeupReceipts = `-- name: DiscardWakeupReceipts :exec
UPDATE issue_wakeup_receipt SET processed_at=now() WHERE wakeup_id= $1 AND processed_at IS NULL
`
func (q *Queries) DiscardWakeupReceipts(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, discardWakeupReceipts, id)
return err
}
const findPendingWakeupTask = `-- name: FindPendingWakeupTask :one
SELECT 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 FROM agent_task_queue WHERE context->>'wakeup_id'= $1::text AND status IN ('queued','dispatched') ORDER BY created_at LIMIT 1 FOR UPDATE
`
func (q *Queries) FindPendingWakeupTask(ctx context.Context, wakeupID string) (AgentTaskQueue, error) {
row := q.db.QueryRow(ctx, findPendingWakeupTask, wakeupID)
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,
)
return i, err
}
const getIssueWakeup = `-- name: GetIssueWakeup :one
SELECT id, workspace_id, issue_id, agent_id, created_by, source_task_id, parent_comment_id, instruction, kind, mode, event_types, filter_agent_id, filter_task_id, interval_seconds, cron_expression, timezone, next_fire_at, enabled, disabled_at, revision, last_task_id, last_error, created_at, updated_at, filter_actor_type, filter_actor_id FROM issue_wakeup WHERE id= $1 AND workspace_id= $2
`
type GetIssueWakeupParams struct {
ID pgtype.UUID `json:"id"`
WorkspaceID pgtype.UUID `json:"workspace_id"`
}
func (q *Queries) GetIssueWakeup(ctx context.Context, arg GetIssueWakeupParams) (IssueWakeup, error) {
row := q.db.QueryRow(ctx, getIssueWakeup, arg.ID, arg.WorkspaceID)
var i IssueWakeup
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.IssueID,
&i.AgentID,
&i.CreatedBy,
&i.SourceTaskID,
&i.ParentCommentID,
&i.Instruction,
&i.Kind,
&i.Mode,
&i.EventTypes,
&i.FilterAgentID,
&i.FilterTaskID,
&i.IntervalSeconds,
&i.CronExpression,
&i.Timezone,
&i.NextFireAt,
&i.Enabled,
&i.DisabledAt,
&i.Revision,
&i.LastTaskID,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.FilterActorType,
&i.FilterActorID,
)
return i, err
}
const listIssueWakeups = `-- name: ListIssueWakeups :many
SELECT w.id,w.workspace_id,w.issue_id,w.agent_id,w.created_by,w.source_task_id,w.parent_comment_id,w.instruction,
w.kind,w.mode,w.event_types,w.filter_actor_type,
(CASE WHEN actor_agent.id IS NOT NULL OR actor_member.user_id IS NOT NULL THEN w.filter_actor_id END)::uuid AS filter_actor_id,
COALESCE(actor_agent.name,actor_user.name,'')::text AS filter_actor_name,
(CASE WHEN source.id IS NOT NULL THEN w.filter_agent_id END)::uuid AS filter_agent_id,
(CASE WHEN EXISTS(SELECT 1 FROM agent_task_queue ft JOIN agent fa ON fa.id=ft.agent_id AND fa.workspace_id=w.workspace_id
WHERE ft.id=w.filter_task_id AND ft.issue_id=w.issue_id AND fa.id=ANY($1::uuid[])) THEN w.filter_task_id END)::uuid AS filter_task_id,
w.interval_seconds,w.cron_expression,w.timezone,w.next_fire_at,w.enabled,w.disabled_at,w.revision,
w.last_task_id,w.last_error,w.created_at,w.updated_at,a.name AS agent_name,source.name AS filter_agent_name,t.status AS last_task_status
FROM issue_wakeup w JOIN agent a ON a.id=w.agent_id AND a.workspace_id=w.workspace_id
LEFT JOIN agent actor_agent ON w.filter_actor_type='agent' AND actor_agent.id=w.filter_actor_id AND actor_agent.workspace_id=w.workspace_id AND actor_agent.id=ANY($1::uuid[])
LEFT JOIN member actor_member ON w.filter_actor_type='member' AND actor_member.user_id=w.filter_actor_id AND actor_member.workspace_id=w.workspace_id
LEFT JOIN "user" actor_user ON actor_user.id=actor_member.user_id
LEFT JOIN agent source ON source.id=w.filter_agent_id AND source.workspace_id=w.workspace_id AND source.id=ANY($1::uuid[])
LEFT JOIN agent_task_queue t ON t.id=w.last_task_id AND t.issue_id=w.issue_id AND t.agent_id=w.agent_id
WHERE w.workspace_id= $2 AND w.issue_id= $3 ORDER BY w.created_at,w.id
`
type ListIssueWakeupsParams struct {
AgentIds []pgtype.UUID `json:"agent_ids"`
WorkspaceID pgtype.UUID `json:"workspace_id"`
IssueID pgtype.UUID `json:"issue_id"`
}
type ListIssueWakeupsRow struct {
ID pgtype.UUID `json:"id"`
WorkspaceID pgtype.UUID `json:"workspace_id"`
IssueID pgtype.UUID `json:"issue_id"`
AgentID pgtype.UUID `json:"agent_id"`
CreatedBy pgtype.UUID `json:"created_by"`
SourceTaskID pgtype.UUID `json:"source_task_id"`
ParentCommentID pgtype.UUID `json:"parent_comment_id"`
Instruction string `json:"instruction"`
Kind string `json:"kind"`
Mode string `json:"mode"`
EventTypes []string `json:"event_types"`
FilterActorType pgtype.Text `json:"filter_actor_type"`
FilterActorID pgtype.UUID `json:"filter_actor_id"`
FilterActorName string `json:"filter_actor_name"`
FilterAgentID pgtype.UUID `json:"filter_agent_id"`
FilterTaskID pgtype.UUID `json:"filter_task_id"`
IntervalSeconds pgtype.Int8 `json:"interval_seconds"`
CronExpression pgtype.Text `json:"cron_expression"`
Timezone string `json:"timezone"`
NextFireAt pgtype.Timestamptz `json:"next_fire_at"`
Enabled bool `json:"enabled"`
DisabledAt pgtype.Timestamptz `json:"disabled_at"`
Revision int64 `json:"revision"`
LastTaskID pgtype.UUID `json:"last_task_id"`
LastError pgtype.Text `json:"last_error"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
AgentName string `json:"agent_name"`
FilterAgentName pgtype.Text `json:"filter_agent_name"`
LastTaskStatus pgtype.Text `json:"last_task_status"`
}
func (q *Queries) ListIssueWakeups(ctx context.Context, arg ListIssueWakeupsParams) ([]ListIssueWakeupsRow, error) {
rows, err := q.db.Query(ctx, listIssueWakeups, arg.AgentIds, arg.WorkspaceID, arg.IssueID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListIssueWakeupsRow{}
for rows.Next() {
var i ListIssueWakeupsRow
if err := rows.Scan(
&i.ID,
&i.WorkspaceID,
&i.IssueID,
&i.AgentID,
&i.CreatedBy,
&i.SourceTaskID,
&i.ParentCommentID,
&i.Instruction,
&i.Kind,
&i.Mode,
&i.EventTypes,
&i.FilterActorType,
&i.FilterActorID,
&i.FilterActorName,
&i.FilterAgentID,
&i.FilterTaskID,
&i.IntervalSeconds,
&i.CronExpression,
&i.Timezone,
&i.NextFireAt,
&i.Enabled,
&i.DisabledAt,
&i.Revision,
&i.LastTaskID,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.AgentName,
&i.FilterAgentName,
&i.LastTaskStatus,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPendingWakeupReceipts = `-- name: ListPendingWakeupReceipts :many
SELECT id, wakeup_id, revision, event_key, event_type, payload, task_id, processed_at, created_at, coalesce_key FROM issue_wakeup_receipt WHERE wakeup_id= $1 AND revision= $2 AND processed_at IS NULL ORDER BY created_at,id LIMIT 100 FOR UPDATE
`
type ListPendingWakeupReceiptsParams struct {
WakeupID pgtype.UUID `json:"wakeup_id"`
Revision int64 `json:"revision"`
}
func (q *Queries) ListPendingWakeupReceipts(ctx context.Context, arg ListPendingWakeupReceiptsParams) ([]IssueWakeupReceipt, error) {
rows, err := q.db.Query(ctx, listPendingWakeupReceipts, arg.WakeupID, arg.Revision)
if err != nil {
return nil, err
}
defer rows.Close()
items := []IssueWakeupReceipt{}
for rows.Next() {
var i IssueWakeupReceipt
if err := rows.Scan(
&i.ID,
&i.WakeupID,
&i.Revision,
&i.EventKey,
&i.EventType,
&i.Payload,
&i.TaskID,
&i.ProcessedAt,
&i.CreatedAt,
&i.CoalesceKey,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listReadyWakeups = `-- name: ListReadyWakeups :many
WITH candidates AS (
SELECT id FROM issue_wakeup WHERE enabled AND kind<>'event' AND next_fire_at<=now()
UNION
SELECT wakeup_id FROM issue_wakeup_receipt WHERE processed_at IS NULL
)
SELECT w.id, w.workspace_id, w.issue_id, w.agent_id, w.created_by, w.source_task_id, w.parent_comment_id, w.instruction, w.kind, w.mode, w.event_types, w.filter_agent_id, w.filter_task_id, w.interval_seconds, w.cron_expression, w.timezone, w.next_fire_at, w.enabled, w.disabled_at, w.revision, w.last_task_id, w.last_error, w.created_at, w.updated_at, w.filter_actor_type, w.filter_actor_id FROM candidates c JOIN issue_wakeup w ON w.id=c.id
ORDER BY w.updated_at,w.id LIMIT 100
`
func (q *Queries) ListReadyWakeups(ctx context.Context) ([]IssueWakeup, error) {
rows, err := q.db.Query(ctx, listReadyWakeups)
if err != nil {
return nil, err
}
defer rows.Close()
items := []IssueWakeup{}
for rows.Next() {
var i IssueWakeup
if err := rows.Scan(
&i.ID,
&i.WorkspaceID,
&i.IssueID,
&i.AgentID,
&i.CreatedBy,
&i.SourceTaskID,
&i.ParentCommentID,
&i.Instruction,
&i.Kind,
&i.Mode,
&i.EventTypes,
&i.FilterAgentID,
&i.FilterTaskID,
&i.IntervalSeconds,
&i.CronExpression,
&i.Timezone,
&i.NextFireAt,
&i.Enabled,
&i.DisabledAt,
&i.Revision,
&i.LastTaskID,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.FilterActorType,
&i.FilterActorID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listWorkspaceWakeupSummaryRows = `-- name: ListWorkspaceWakeupSummaryRows :many
WITH ranked AS (
SELECT w.issue_id,w.id,w.agent_id,a.name AS agent_name,w.kind,w.mode,w.event_types,w.filter_actor_type,
(CASE WHEN actor_agent.id IS NOT NULL OR actor_member.user_id IS NOT NULL THEN w.filter_actor_id END)::uuid AS filter_actor_id,
COALESCE(actor_agent.name,actor_user.name,'')::text AS filter_actor_name,
(CASE WHEN EXISTS(SELECT 1 FROM agent_task_queue ft JOIN agent fa ON fa.id=ft.agent_id AND fa.workspace_id=w.workspace_id
WHERE ft.id=w.filter_task_id AND ft.issue_id=w.issue_id AND fa.id=ANY($1::uuid[])) THEN w.filter_task_id END)::uuid AS filter_task_id,
source.name AS filter_agent_name,w.interval_seconds,w.cron_expression,w.timezone,w.next_fire_at,
count(*) OVER(PARTITION BY w.issue_id) AS active_count,
count(*) FILTER(WHERE w.kind='event') OVER(PARTITION BY w.issue_id) AS event_count,
row_number() OVER(PARTITION BY w.issue_id ORDER BY w.next_fire_at NULLS LAST,w.created_at,w.id) AS rank
FROM issue_wakeup w
JOIN issue i ON i.id=w.issue_id AND i.workspace_id=w.workspace_id
JOIN agent a ON a.id=w.agent_id AND a.workspace_id=w.workspace_id
LEFT JOIN agent actor_agent ON w.filter_actor_type='agent' AND actor_agent.id=w.filter_actor_id AND actor_agent.workspace_id=w.workspace_id AND actor_agent.id=ANY($1::uuid[])
LEFT JOIN member actor_member ON w.filter_actor_type='member' AND actor_member.user_id=w.filter_actor_id AND actor_member.workspace_id=w.workspace_id
LEFT JOIN "user" actor_user ON actor_user.id=actor_member.user_id
LEFT JOIN agent source ON source.id=w.filter_agent_id AND source.workspace_id=w.workspace_id AND source.id=ANY($1::uuid[])
WHERE w.workspace_id= $2 AND w.enabled
AND i.status NOT IN ('done','cancelled')
AND NOT EXISTS(SELECT 1 FROM issue_status s WHERE s.workspace_id=i.workspace_id AND s.key=i.status AND s.category IN ('done','closed'))
)
SELECT issue_id,id,agent_id,agent_name,kind,mode,event_types,filter_actor_type,filter_actor_id,filter_actor_name,filter_task_id,filter_agent_name,interval_seconds,cron_expression,timezone,next_fire_at,active_count,event_count
FROM ranked WHERE rank<=3 ORDER BY issue_id,rank
`
type ListWorkspaceWakeupSummaryRowsParams struct {
AgentIds []pgtype.UUID `json:"agent_ids"`
WorkspaceID pgtype.UUID `json:"workspace_id"`
}
type ListWorkspaceWakeupSummaryRowsRow struct {
IssueID pgtype.UUID `json:"issue_id"`
ID pgtype.UUID `json:"id"`
AgentID pgtype.UUID `json:"agent_id"`
AgentName string `json:"agent_name"`
Kind string `json:"kind"`
Mode string `json:"mode"`
EventTypes []string `json:"event_types"`
FilterActorType pgtype.Text `json:"filter_actor_type"`
FilterActorID pgtype.UUID `json:"filter_actor_id"`
FilterActorName string `json:"filter_actor_name"`
FilterTaskID pgtype.UUID `json:"filter_task_id"`
FilterAgentName pgtype.Text `json:"filter_agent_name"`
IntervalSeconds pgtype.Int8 `json:"interval_seconds"`
CronExpression pgtype.Text `json:"cron_expression"`
Timezone string `json:"timezone"`
NextFireAt pgtype.Timestamptz `json:"next_fire_at"`
ActiveCount int64 `json:"active_count"`
EventCount int64 `json:"event_count"`
}
// No prompts/history; at most three previews per issue plus exact counts.
func (q *Queries) ListWorkspaceWakeupSummaryRows(ctx context.Context, arg ListWorkspaceWakeupSummaryRowsParams) ([]ListWorkspaceWakeupSummaryRowsRow, error) {
rows, err := q.db.Query(ctx, listWorkspaceWakeupSummaryRows, arg.AgentIds, arg.WorkspaceID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListWorkspaceWakeupSummaryRowsRow{}
for rows.Next() {
var i ListWorkspaceWakeupSummaryRowsRow
if err := rows.Scan(
&i.IssueID,
&i.ID,
&i.AgentID,
&i.AgentName,
&i.Kind,
&i.Mode,
&i.EventTypes,
&i.FilterActorType,
&i.FilterActorID,
&i.FilterActorName,
&i.FilterTaskID,
&i.FilterAgentName,
&i.IntervalSeconds,
&i.CronExpression,
&i.Timezone,
&i.NextFireAt,
&i.ActiveCount,
&i.EventCount,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const lockIssueWakeup = `-- name: LockIssueWakeup :one
SELECT id, workspace_id, issue_id, agent_id, created_by, source_task_id, parent_comment_id, instruction, kind, mode, event_types, filter_agent_id, filter_task_id, interval_seconds, cron_expression, timezone, next_fire_at, enabled, disabled_at, revision, last_task_id, last_error, created_at, updated_at, filter_actor_type, filter_actor_id FROM issue_wakeup WHERE id= $1 FOR UPDATE
`
func (q *Queries) LockIssueWakeup(ctx context.Context, id pgtype.UUID) (IssueWakeup, error) {
row := q.db.QueryRow(ctx, lockIssueWakeup, id)
var i IssueWakeup
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.IssueID,
&i.AgentID,
&i.CreatedBy,
&i.SourceTaskID,
&i.ParentCommentID,
&i.Instruction,
&i.Kind,
&i.Mode,
&i.EventTypes,
&i.FilterAgentID,
&i.FilterTaskID,
&i.IntervalSeconds,
&i.CronExpression,
&i.Timezone,
&i.NextFireAt,
&i.Enabled,
&i.DisabledAt,
&i.Revision,
&i.LastTaskID,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.FilterActorType,
&i.FilterActorID,
)
return i, err
}
const lockWakeupIssue = `-- name: LockWakeupIssue :one
SELECT id, workspace_id, title, description, status, priority, assignee_type, assignee_id, creator_type, creator_id, parent_issue_id, acceptance_criteria, context_refs, position, due_date, created_at, updated_at, number, project_id, origin_type, origin_id, first_executed_at, start_date, metadata, stage, properties, revision, last_activity_at, triage_state FROM issue WHERE id= $1 FOR NO KEY UPDATE
`
func (q *Queries) LockWakeupIssue(ctx context.Context, id pgtype.UUID) (Issue, error) {
row := q.db.QueryRow(ctx, lockWakeupIssue, id)
var i Issue
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.Title,
&i.Description,
&i.Status,
&i.Priority,
&i.AssigneeType,
&i.AssigneeID,
&i.CreatorType,
&i.CreatorID,
&i.ParentIssueID,
&i.AcceptanceCriteria,
&i.ContextRefs,
&i.Position,
&i.DueDate,
&i.CreatedAt,
&i.UpdatedAt,
&i.Number,
&i.ProjectID,
&i.OriginType,
&i.OriginID,
&i.FirstExecutedAt,
&i.StartDate,
&i.Metadata,
&i.Stage,
&i.Properties,
&i.Revision,
&i.LastActivityAt,
&i.TriageState,
)
return i, err
}
const lockWakeupSourceTask = `-- name: LockWakeupSourceTask :one
SELECT 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 FROM agent_task_queue WHERE id= $1 AND issue_id= $2 FOR UPDATE NOWAIT
`
type LockWakeupSourceTaskParams struct {
ID pgtype.UUID `json:"id"`
IssueID pgtype.UUID `json:"issue_id"`
}
func (q *Queries) LockWakeupSourceTask(ctx context.Context, arg LockWakeupSourceTaskParams) (AgentTaskQueue, error) {
row := q.db.QueryRow(ctx, lockWakeupSourceTask, arg.ID, arg.IssueID)
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,
)
return i, err
}
const locklessWakeup = `-- name: LocklessWakeup :one
SELECT id, workspace_id, issue_id, agent_id, created_by, source_task_id, parent_comment_id, instruction, kind, mode, event_types, filter_agent_id, filter_task_id, interval_seconds, cron_expression, timezone, next_fire_at, enabled, disabled_at, revision, last_task_id, last_error, created_at, updated_at, filter_actor_type, filter_actor_id FROM issue_wakeup WHERE id= $1
`
func (q *Queries) LocklessWakeup(ctx context.Context, id pgtype.UUID) (IssueWakeup, error) {
row := q.db.QueryRow(ctx, locklessWakeup, id)
var i IssueWakeup
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.IssueID,
&i.AgentID,
&i.CreatedBy,
&i.SourceTaskID,
&i.ParentCommentID,
&i.Instruction,
&i.Kind,
&i.Mode,
&i.EventTypes,
&i.FilterAgentID,
&i.FilterTaskID,
&i.IntervalSeconds,
&i.CronExpression,
&i.Timezone,
&i.NextFireAt,
&i.Enabled,
&i.DisabledAt,
&i.Revision,
&i.LastTaskID,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.FilterActorType,
&i.FilterActorID,
)
return i, err
}
const noteWakeupFailure = `-- name: NoteWakeupFailure :exec
UPDATE issue_wakeup SET last_error=$1,updated_at=clock_timestamp() WHERE id= $2
`
type NoteWakeupFailureParams struct {
LastError pgtype.Text `json:"last_error"`
ID pgtype.UUID `json:"id"`
}
func (q *Queries) NoteWakeupFailure(ctx context.Context, arg NoteWakeupFailureParams) error {
_, err := q.db.Exec(ctx, noteWakeupFailure, arg.LastError, arg.ID)
return err
}
const recordWakeupReceipt = `-- name: RecordWakeupReceipt :one
INSERT INTO issue_wakeup_receipt(id,wakeup_id,revision,event_key,event_type,payload)
VALUES($1,$2,$3,$4,$5,$6)
ON CONFLICT(wakeup_id,revision,event_key) DO UPDATE SET event_key=EXCLUDED.event_key RETURNING id, wakeup_id, revision, event_key, event_type, payload, task_id, processed_at, created_at, coalesce_key
`
type RecordWakeupReceiptParams struct {
ID pgtype.UUID `json:"id"`
WakeupID pgtype.UUID `json:"wakeup_id"`
Revision int64 `json:"revision"`
EventKey string `json:"event_key"`
EventType string `json:"event_type"`
Payload []byte `json:"payload"`
}
func (q *Queries) RecordWakeupReceipt(ctx context.Context, arg RecordWakeupReceiptParams) (IssueWakeupReceipt, error) {
row := q.db.QueryRow(ctx, recordWakeupReceipt,
arg.ID,
arg.WakeupID,
arg.Revision,
arg.EventKey,
arg.EventType,
arg.Payload,
)
var i IssueWakeupReceipt
err := row.Scan(
&i.ID,
&i.WakeupID,
&i.Revision,
&i.EventKey,
&i.EventType,
&i.Payload,
&i.TaskID,
&i.ProcessedAt,
&i.CreatedAt,
&i.CoalesceKey,
)
return i, err
}
const replaceWakeupEvidence = `-- name: ReplaceWakeupEvidence :one
UPDATE agent_task_queue SET handoff_note=$1, context=COALESCE(context,'{}'::jsonb) || jsonb_build_object('wakeup_evidence', $2::jsonb) WHERE id= $3 AND status='queued' 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
`
type ReplaceWakeupEvidenceParams struct {
HandoffNote pgtype.Text `json:"handoff_note"`
WakeupEvidence []byte `json:"wakeup_evidence"`
ID pgtype.UUID `json:"id"`
}
func (q *Queries) ReplaceWakeupEvidence(ctx context.Context, arg ReplaceWakeupEvidenceParams) (AgentTaskQueue, error) {
row := q.db.QueryRow(ctx, replaceWakeupEvidence, arg.HandoffNote, arg.WakeupEvidence, 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,
)
return i, err
}
const touchWakeupDispatch = `-- name: TouchWakeupDispatch :exec
UPDATE issue_wakeup SET updated_at=clock_timestamp() WHERE id= $1
`
// Move blocked configurations to the back of the scan so one noisy issue
// cannot monopolize the bounded batch.
func (q *Queries) TouchWakeupDispatch(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, touchWakeupDispatch, id)
return err
}