feat: add notification for task status (#19965)

## Description

Send a notification to the workspace owner when an AI task’s app state
becomes `Working` or `Idle`.
An AI task is identified by a workspace build with `HasAITask = true`
and `AITaskSidebarAppID` matching the agent app’s ID.

## Changes

* Add `TemplateTaskWorking` notification template.
* Add `TemplateTaskIdle` notification template.
* Add `GetLatestWorkspaceAppStatusesByAppID` SQL query to get the
workspace app statuses ordered by latest first.
* Update `PATCH /workspaceagents/me/app-status` to enqueue:
  * `TemplateTaskWorking` when state transitions to `working`
  * `TemplateTaskIdle` when state transitions to `idle`
* Notification labels include:
  * `task`: task initial prompt
  * `workspace`: workspace name
* Notification dedupe: include a minute-bucketed timestamp (UTC
truncated to the minute) in the enqueue data to allow identical content
to resend within the same day (but not more than once per minute).

Closes: https://github.com/coder/coder/issues/19776
This commit is contained in:
Susana Ferreira
2025-09-29 16:44:53 +01:00
committed by GitHub
parent abdea7213a
commit fdb0267e5d
18 changed files with 689 additions and 1 deletions
@@ -0,0 +1,4 @@
-- Remove Task 'working' transition template notification
DELETE FROM notification_templates WHERE id = 'bd4b7168-d05e-4e19-ad0f-3593b77aa90f';
-- Remove Task 'idle' transition template notification
DELETE FROM notification_templates WHERE id = 'd4a6271c-cced-4ed0-84ad-afd02a9c7799';
@@ -0,0 +1,63 @@
-- Task transition to 'working' status
INSERT INTO notification_templates (
id,
name,
title_template,
body_template,
actions,
"group",
method,
kind,
enabled_by_default
) VALUES (
'bd4b7168-d05e-4e19-ad0f-3593b77aa90f',
'Task Working',
E'Task ''{{.Labels.workspace}}'' is working',
E'The task ''{{.Labels.task}}'' transitioned to a working state.',
'[
{
"label": "View task",
"url": "{{base_url}}/tasks/{{.UserUsername}}/{{.Labels.workspace}}"
},
{
"label": "View workspace",
"url": "{{base_url}}/@{{.UserUsername}}/{{.Labels.workspace}}"
}
]'::jsonb,
'Task Events',
NULL,
'system'::notification_template_kind,
true
);
-- Task transition to 'idle' status
INSERT INTO notification_templates (
id,
name,
title_template,
body_template,
actions,
"group",
method,
kind,
enabled_by_default
) VALUES (
'd4a6271c-cced-4ed0-84ad-afd02a9c7799',
'Task Idle',
E'Task ''{{.Labels.workspace}}'' is idle',
E'The task ''{{.Labels.task}}'' is idle and ready for input.',
'[
{
"label": "View task",
"url": "{{base_url}}/tasks/{{.UserUsername}}/{{.Labels.workspace}}"
},
{
"label": "View workspace",
"url": "{{base_url}}/@{{.UserUsername}}/{{.Labels.workspace}}"
}
]'::jsonb,
'Task Events',
NULL,
'system'::notification_template_kind,
true
);