Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Merged
ssncferreira merged 9 commits intomainfromssncferreira/feat-tasks-notifications
Sep 29, 2025

Conversation

ssncferreira
Copy link
Contributor

@ssncferreirassncferreira commentedSep 25, 2025
edited
Loading

Description

Send a notification to the workspace owner when an AI task’s app state becomesWorking orIdle.
An AI task is identified by a workspace build withHasAITask = true andAITaskSidebarAppID matching the agent app’s ID.

Changes

  • AddTemplateTaskWorking notification template.
  • AddTemplateTaskIdle notification template.
  • AddGetLatestWorkspaceAppStatusesByAppID SQL query to get the workspace app statuses ordered by latest first.
  • UpdatePATCH /workspaceagents/me/app-status to enqueue:
    • TemplateTaskWorking when state transitions toworking
    • TemplateTaskIdle when state transitions toidle
  • 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:#19776

@ssncferreirassncferreiraforce-pushed thessncferreira/feat-tasks-notifications branch from62ff41a tob20b801CompareSeptember 25, 2025 17:37
enabled_by_default
) VALUES (
'bd4b7168-d05e-4e19-ad0f-3593b77aa90f',
'Task Working',
Copy link
ContributorAuthor

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?

Comment on lines 442 to 443
ifworkspaceBuild.HasAITask.Valid&&workspaceBuild.HasAITask.Bool&&
workspaceBuild.AITaskSidebarAppID.Valid&&workspaceBuild.AITaskSidebarAppID.UUID==app.ID {
Copy link
ContributorAuthor

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?

Copy link
Member

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.

ssncferreira reacted with thumbs up emoji
@ssncferreirassncferreira marked this pull request as ready for reviewSeptember 25, 2025 17:49
Comment on lines 442 to 443
ifworkspaceBuild.HasAITask.Valid&&workspaceBuild.HasAITask.Bool&&
workspaceBuild.AITaskSidebarAppID.Valid&&workspaceBuild.AITaskSidebarAppID.UUID==app.ID {
Copy link
Member

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.

ssncferreira reacted with thumbs up emoji
notificationTemplate=notifications.TemplateTaskIdle
}

if_,err:=api.NotificationsEnqueuer.EnqueueWithData(
Copy link
Member

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"

ssncferreira reacted with thumbs up emoji
Copy link
ContributorAuthor

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

Copy link
Member

@mafredrimafredri left a 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.

// 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),
Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Member

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).

DanielleMaywood reacted with thumbs up emoji
Copy link
ContributorAuthor

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 😊

Copy link
Contributor

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?

Copy link
Member

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.

Copy link
Member

@mafredrimafredriSep 26, 2025
edited
Loading

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.

Copy link
ContributorAuthor

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

Copy link
Member

@johnstcnjohnstcn left a 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.

Copy link
Member

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!

ssncferreira reacted with thumbs up emoji
Comment on lines +76 to +81
-- name: GetLatestWorkspaceAppStatusesByAppID :many
SELECT*
FROM workspace_app_statuses
WHERE app_id= @app_id::uuid
ORDER BY created_atDESC, idDESC;

Copy link
Member

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?

Copy link
ContributorAuthor

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.

Copy link
Contributor

@DanielleMaywoodDanielleMaywood left a 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 {
Copy link
Contributor

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

ssncferreira reacted with eyes emoji
Copy link
ContributorAuthor

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.

Copy link
Member

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.

@ssncferreirassncferreira merged commitfdb0267 intomainSep 29, 2025
31 checks passed
@ssncferreirassncferreira deleted the ssncferreira/feat-tasks-notifications branchSeptember 29, 2025 15:44
@github-actionsgithub-actionsbot locked and limited conversation to collaboratorsSep 29, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.
Reviewers

@johnstcnjohnstcnjohnstcn approved these changes

@DanielleMaywoodDanielleMaywoodDanielleMaywood approved these changes

@mafredrimafredriAwaiting requested review from mafredri

Assignees

@ssncferreirassncferreira

Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Notification for Task status change active <> idle
4 participants
@ssncferreira@mafredri@johnstcn@DanielleMaywood

[8]ページ先頭

©2009-2025 Movatter.jp