@@ -19,6 +19,7 @@ import (
1919"strings"
2020"sync"
2121"time"
22+ "unicode/utf8"
2223
2324"github.com/elastic/go-sysinfo"
2425"github.com/google/uuid"
@@ -730,6 +731,19 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
730731}
731732return nil
732733})
734+ eg .Go (func ()error {
735+ dbTasks ,err := r .options .Database .ListTasks (ctx , database.ListTasksParams {
736+ OwnerID :uuid .Nil ,
737+ OrganizationID :uuid .Nil ,
738+ })
739+ if err != nil {
740+ return err
741+ }
742+ for _ ,dbTask := range dbTasks {
743+ snapshot .Tasks = append (snapshot .Tasks ,ConvertTask (dbTask ))
744+ }
745+ return nil
746+ })
733747
734748err := eg .Wait ()
735749if err != nil {
@@ -914,6 +928,22 @@ func ConvertWorkspaceResourceMetadata(metadata database.WorkspaceResourceMetadat
914928}
915929}
916930
931+ // ConvertTask anonymizes a Task.
932+ func ConvertTask (task database.Task )Task {
933+ return Task {
934+ ID :task .ID ,
935+ OrganizationID :task .OrganizationID ,
936+ OwnerID :task .OwnerID ,
937+ Name :task .Name ,
938+ WorkspaceID :task .WorkspaceID ,
939+ TemplateVersionID :task .TemplateVersionID ,
940+ PromptHash :fmt .Sprintf ("%x" ,sha256 .New ().Sum ([]byte (task .Prompt ))),
941+ PromptLength :utf8 .RuneCountInString (task .Prompt ),
942+ CreatedAt :task .CreatedAt ,
943+ Status :string (task .Status ),
944+ }
945+ }
946+
917947func shouldSendRawModuleSource (source string )bool {
918948return strings .Contains (source ,"registry.coder.com" )
919949}
@@ -1205,6 +1235,7 @@ type Snapshot struct {
12051235Workspaces []Workspace `json:"workspaces"`
12061236NetworkEvents []NetworkEvent `json:"network_events"`
12071237Organizations []Organization `json:"organizations"`
1238+ Tasks []Task `json:"tasks"`
12081239TelemetryItems []TelemetryItem `json:"telemetry_items"`
12091240UserTailnetConnections []UserTailnetConnection `json:"user_tailnet_connections"`
12101241PrebuiltWorkspaces []PrebuiltWorkspace `json:"prebuilt_workspaces"`
@@ -1753,6 +1784,19 @@ type Organization struct {
17531784CreatedAt time.Time `json:"created_at"`
17541785}
17551786
1787+ type Task struct {
1788+ ID uuid.UUID `json:"id"`
1789+ OrganizationID uuid.UUID `json:"organization_id"`
1790+ OwnerID uuid.UUID `json:"owner_id"`
1791+ Name string `json:"name"`
1792+ WorkspaceID uuid.NullUUID `json:"workspace_id"`
1793+ TemplateVersionID uuid.UUID `json:"template_version_id"`
1794+ PromptHash string `json:"hashed_prompt"`
1795+ PromptLength int `json:"prompt_length"`
1796+ CreatedAt time.Time `json:"created_at"`
1797+ Status string `json:"status"`
1798+ }
1799+
17561800type telemetryItemKey string
17571801
17581802// The comment below gets rid of the warning that the name "TelemetryItemKey" has