-- ========================================== -- Chat Switchboard — 019 Tasks -- ========================================== -- Task definitions and run history for autonomous agents. -- Consolidated v0.28.0: merges 026 + 027 (webhook_secret inline). -- v0.28.0-cs3: trigger_token, action task_type, queued run status. -- ========================================== -- ========================================= -- TASK DEFINITIONS -- ========================================= CREATE TABLE IF NOT EXISTS tasks ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, team_id UUID REFERENCES teams(id) ON DELETE SET NULL, name TEXT NOT NULL, description TEXT DEFAULT '', scope TEXT NOT NULL DEFAULT 'personal' CHECK (scope IN ('personal', 'team', 'global')), -- What to run task_type TEXT NOT NULL DEFAULT 'prompt' CHECK (task_type IN ('prompt', 'workflow', 'action', 'system')), system_function TEXT DEFAULT '', persona_id UUID REFERENCES personas(id) ON DELETE SET NULL, model_id TEXT, system_prompt TEXT DEFAULT '', user_prompt TEXT DEFAULT '', workflow_id UUID REFERENCES workflows(id) ON DELETE SET NULL, tool_grants JSONB, -- Schedule: cron expression, "once", or "webhook" schedule TEXT NOT NULL, timezone TEXT NOT NULL DEFAULT 'UTC', is_active BOOLEAN NOT NULL DEFAULT true, -- Webhook trigger (inbound) — token-based auth for /hooks/t/:token trigger_token TEXT UNIQUE, -- Execution policy max_tokens INTEGER NOT NULL DEFAULT 4096, max_tool_calls INTEGER NOT NULL DEFAULT 10, max_wall_clock INTEGER NOT NULL DEFAULT 300, output_mode TEXT NOT NULL DEFAULT 'channel' CHECK (output_mode IN ('channel', 'note', 'webhook')), output_channel_id UUID REFERENCES channels(id) ON DELETE SET NULL, webhook_url TEXT, webhook_secret TEXT, -- Provider routing provider_config_id UUID REFERENCES provider_configs(id) ON DELETE SET NULL, -- Notifications notify_on_complete BOOLEAN NOT NULL DEFAULT false, notify_on_failure BOOLEAN NOT NULL DEFAULT true, -- Bookkeeping last_run_at TIMESTAMPTZ, next_run_at TIMESTAMPTZ, run_count INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_tasks_next_run ON tasks (next_run_at) WHERE is_active = true; CREATE INDEX IF NOT EXISTS idx_tasks_owner ON tasks (owner_id); CREATE INDEX IF NOT EXISTS idx_tasks_team ON tasks (team_id); CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_trigger_token ON tasks (trigger_token) WHERE trigger_token IS NOT NULL; -- ========================================= -- TASK RUN HISTORY -- ========================================= CREATE TABLE IF NOT EXISTS task_runs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, channel_id UUID REFERENCES channels(id) ON DELETE SET NULL, status TEXT NOT NULL DEFAULT 'running' CHECK (status IN ('queued', 'running', 'completed', 'failed', 'budget_exceeded', 'cancelled')), trigger_payload TEXT, started_at TIMESTAMPTZ NOT NULL DEFAULT now(), completed_at TIMESTAMPTZ, tokens_used INTEGER DEFAULT 0, tool_calls INTEGER DEFAULT 0, wall_clock INTEGER DEFAULT 0, error TEXT ); CREATE INDEX IF NOT EXISTS idx_task_runs_task ON task_runs (task_id); CREATE INDEX IF NOT EXISTS idx_task_runs_status ON task_runs (task_id, status);