diff --git a/coderd/aitasks_test.go b/coderd/aitasks_test.go index 6425e06c77..4172cccda6 100644 --- a/coderd/aitasks_test.go +++ b/coderd/aitasks_test.go @@ -1008,16 +1008,26 @@ func TestTasksNotification(t *testing.T) { isNotificationSent: false, taskPrompt: "NonNotifiedTransition", }, - // Should send TemplateTaskWorking when the AI task transitions to 'Working'. + // Should NOT send TemplateTaskWorking when the AI task's FIRST status is 'Working' (obvious state). { name: "TemplateTaskWorking", latestAppStatuses: nil, newAppStatus: codersdk.WorkspaceAppStatusStateWorking, isAITask: true, - isNotificationSent: true, + isNotificationSent: false, notificationTemplate: notifications.TemplateTaskWorking, taskPrompt: "TemplateTaskWorking", }, + // Should send TemplateTaskIdle when the AI task's FIRST status is 'Idle' (task completed immediately). + { + name: "InitialTemplateTaskIdle", + latestAppStatuses: nil, + newAppStatus: codersdk.WorkspaceAppStatusStateIdle, + isAITask: true, + isNotificationSent: true, + notificationTemplate: notifications.TemplateTaskIdle, + taskPrompt: "InitialTemplateTaskIdle", + }, // Should send TemplateTaskWorking when the AI task transitions to 'Working' from 'Idle'. { name: "TemplateTaskWorkingFromIdle", diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 0e6d0430e3..51654380e5 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -471,6 +471,13 @@ func (api *API) enqueueAITaskStateNotification( return } + // Skip the initial "Working" notification when task first starts. + // This is obvious to the user since they just created the task. + // We still notify on first "Idle" status and all subsequent transitions. + if len(latestAppStatus) == 0 && newAppStatus == codersdk.WorkspaceAppStatusStateWorking { + return + } + // Use the task prompt as the "task" label, fallback to workspace name parameters, err := api.Database.GetWorkspaceBuildParameters(ctx, workspaceBuild.ID) if err != nil {