- Notifications
You must be signed in to change notification settings - Fork1k
feat: add notification for task status#19965
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
62ff41a
tob20b801
Compareenabled_by_default | ||
) VALUES ( | ||
'bd4b7168-d05e-4e19-ad0f-3593b77aa90f', | ||
'Task Working', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I kept the terminology aligned with the current workspace agent app status (Working
,Idle
). In PR:https://github.com/coder/coder/pull/19773/files#diff-1894d4f2ccb1125739e504fc6d8d3a7daeec9dd829a81c342cf28f3e92efbf58R2-R7 I see the task status types differ. Is that finalized? If yes, should I update this PR to adopt the new task status terms?
coderd/workspaceagents.go Outdated
ifworkspaceBuild.HasAITask.Valid&&workspaceBuild.HasAITask.Bool&& | ||
workspaceBuild.AITaskSidebarAppID.Valid&&workspaceBuild.AITaskSidebarAppID.UUID==app.ID { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
With the current data model, this is the correct way to determine if a workspace agent app is an AI task, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
For now, yes. This will need to be refactored later.
Uh oh!
There was an error while loading.Please reload this page.
coderd/workspaceagents.go Outdated
ifworkspaceBuild.HasAITask.Valid&&workspaceBuild.HasAITask.Bool&& | ||
workspaceBuild.AITaskSidebarAppID.Valid&&workspaceBuild.AITaskSidebarAppID.UUID==app.ID { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
For now, yes. This will need to be refactored later.
coderd/workspaceagents.go Outdated
notificationTemplate=notifications.TemplateTaskIdle | ||
} | ||
if_,err:=api.NotificationsEnqueuer.EnqueueWithData( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Before we enqueue a notification, we should ensure that the new task status is different to the previous. An agent could insert multiple app statuses with the same state but different messages e.g.
- "working / doing thing A"
- "working / doing thing B"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Ok, that is good to know. I was not aware it was possible for a task to transition to the same status. Addressed in06ed8c7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Looks good to me, nice work 👍🏻. Not much to add from what Cian already, just one question/potential gotcha.
coderd/workspaceagents.go Outdated
// Include a minute-bucketed timestamp to bypass per-day dedupe, | ||
// allowing identical content to resend within the same day | ||
// (but not more than once per minute) | ||
"dedupe_bypass_ts":api.Clock.Now().UTC().Truncate(time.Minute), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
How does this work if the task quickly jumps between working/idle/working? Is there a chance we miss the second working and never emit it? If yes, I think that would lead to bad UX as the notifications are untrustworthy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
If a task were to go through the state transitionIdle -> Working -> Idle -> Working -> Idle
all within the space of a minute, you'd only get the initial-> Working
and-> Idle
notifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Thanks for confirming, that's what I suspected. It gets a bit funky when we're bordering on the minute mark.
14:39:00 Working
14:39:29 Idle
14:39:59 Working
14:40:30 Idle
We get Working -> Idle -> Idle (alt. Idle -> Working -> Working).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Yes, that’s a good point. There are still scenarios where the system could skip some notification types, resulting in the same type being sent back-to-back. The minute-level dedupe was intended as a safeguard to avoid spamming users. Based on the problem definition "By definition tasks may take quite a long time to be completed. We do not want the users to stare at the screen waiting because that invalidates the whole purpose." the assumption was that these transitions wouldn’t happen very quickly.
Instead of truncating to the minute, should we use the exact timestamp? That would avoid missing intermediate states, but it does increase the risk of too many notifications. Open to suggestions 😊
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Unfortunately I think there is no perfect solution here. Wecould still truncate to the second, but like before, any truncation runs the risk of missing a notification. I'd be satisfied with truncating it down to the second.@mafredri thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'd rather risk missing some notifications than spamming and potentially overloading coderd or whatever notification backed is in use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Second or even 5-10 second truncate would work. 👍🏻 Especially if we implement the safeguard that Cian mentioned, i.e. previous status must have been different from current status, then we minimize the risk of spam.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Added a 10-second truncate to the dedupe key and a check to send notifications only on new transitions.
Addressed in06ed8c7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Some comments below, but I don't need to review again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Obligatory reminder to check migration number before merge!
-- name: GetLatestWorkspaceAppStatusesByAppID :many | ||
SELECT* | ||
FROM workspace_app_statuses | ||
WHERE app_id= @app_id::uuid | ||
ORDER BY created_atDESC, idDESC; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Would it make sense to instead add anORDER BY
clause toGetWorkspaceAppStatusesByAppIDs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
We could addORDER BY
toGetWorkspaceAppStatusesByAppIDs
and rename it to reflect the ordering (e.g.,GetLatestWorkspaceAppStatusesByAppIDs
). For this PR I only need one app, newest-first, so the dedicated query seemed to keep things clearer.
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Approve with a non-blocking issue:
} | ||
func (q*querier)GetLatestWorkspaceAppStatusesByAppID(ctx context.Context,appID uuid.UUID) ([]database.WorkspaceAppStatus,error) { | ||
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I realize the other functions around here do the same but I think we were wanting to stop introducing more uses ofResourceSystem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
AFAIK, there isn’t a dedicated resource for workspace apps, so operations on them currently authorize againstrbac.ResourceSystem
. I’m not sure what the best alternative is, skipping the authorization check would make this data accessible to anyone, which we don’t want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This is unfortunately a pre-existing issue from the introduction of app statuses. It may be worth addressing in a follow-up.
fdb0267
intomainUh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Description
Send a notification to the workspace owner when an AI task’s app state becomes
Working
orIdle
.An AI task is identified by a workspace build with
HasAITask = true
andAITaskSidebarAppID
matching the agent app’s ID.Changes
TemplateTaskWorking
notification template.TemplateTaskIdle
notification template.GetLatestWorkspaceAppStatusesByAppID
SQL query to get the workspace app statuses ordered by latest first.PATCH /workspaceagents/me/app-status
to enqueue:TemplateTaskWorking
when state transitions toworking
TemplateTaskIdle
when state transitions toidle
task
: task initial promptworkspace
: workspace nameCloses:#19776