diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql
index e4cee2333efc4..b37ffe45e95c6 100644
--- a/coderd/database/dump.sql
+++ b/coderd/database/dump.sql
@@ -1553,7 +1553,8 @@ CREATE TABLE template_versions (
external_auth_providers jsonb DEFAULT '[]'::jsonb NOT NULL,
message character varying(1048576) DEFAULT ''::character varying NOT NULL,
archived boolean DEFAULT false NOT NULL,
- source_example_id text
+ source_example_id text,
+ has_ai_task boolean DEFAULT false NOT NULL
);
COMMENT ON COLUMN template_versions.external_auth_providers IS 'IDs of External auth providers for a specific template version';
@@ -1583,6 +1584,7 @@ CREATE VIEW template_version_with_user AS
template_versions.message,
template_versions.archived,
template_versions.source_example_id,
+ template_versions.has_ai_task,
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
COALESCE(visible_users.username, ''::text) AS created_by_username,
COALESCE(visible_users.name, ''::text) AS created_by_name
@@ -2080,7 +2082,9 @@ CREATE TABLE workspace_builds (
reason build_reason DEFAULT 'initiator'::build_reason NOT NULL,
daily_cost integer DEFAULT 0 NOT NULL,
max_deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
- template_version_preset_id uuid
+ template_version_preset_id uuid,
+ has_ai_task boolean DEFAULT false NOT NULL,
+ ai_tasks_sidebar_app_id uuid
);
CREATE VIEW workspace_build_with_user AS
@@ -2099,6 +2103,8 @@ CREATE VIEW workspace_build_with_user AS
workspace_builds.daily_cost,
workspace_builds.max_deadline,
workspace_builds.template_version_preset_id,
+ workspace_builds.has_ai_task,
+ workspace_builds.ai_tasks_sidebar_app_id,
COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
COALESCE(visible_users.username, ''::text) AS initiator_by_username,
COALESCE(visible_users.name, ''::text) AS initiator_by_name
@@ -2667,6 +2673,8 @@ CREATE INDEX idx_tailnet_tunnels_dst_id ON tailnet_tunnels USING hash (dst_id);
CREATE INDEX idx_tailnet_tunnels_src_id ON tailnet_tunnels USING hash (src_id);
+CREATE INDEX idx_template_versions_has_ai_task ON template_versions USING btree (has_ai_task);
+
CREATE UNIQUE INDEX idx_unique_preset_name ON template_version_presets USING btree (name, template_version_id);
CREATE INDEX idx_user_deleted_deleted_at ON user_deleted USING btree (deleted_at);
@@ -3063,6 +3071,9 @@ ALTER TABLE ONLY workspace_apps
ALTER TABLE ONLY workspace_build_parameters
ADD CONSTRAINT workspace_build_parameters_workspace_build_id_fkey FOREIGN KEY (workspace_build_id) REFERENCES workspace_builds(id) ON DELETE CASCADE;
+ALTER TABLE ONLY workspace_builds
+ ADD CONSTRAINT workspace_builds_ai_tasks_sidebar_app_id_fkey FOREIGN KEY (ai_tasks_sidebar_app_id) REFERENCES workspace_apps(id);
+
ALTER TABLE ONLY workspace_builds
ADD CONSTRAINT workspace_builds_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
diff --git a/coderd/database/foreign_key_constraint.go b/coderd/database/foreign_key_constraint.go
index d6b87ddff5376..eaec2d2495337 100644
--- a/coderd/database/foreign_key_constraint.go
+++ b/coderd/database/foreign_key_constraint.go
@@ -82,6 +82,7 @@ const (
ForeignKeyWorkspaceAppStatusesWorkspaceID ForeignKeyConstraint = "workspace_app_statuses_workspace_id_fkey" // ALTER TABLE ONLY workspace_app_statuses ADD CONSTRAINT workspace_app_statuses_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id);
ForeignKeyWorkspaceAppsAgentID ForeignKeyConstraint = "workspace_apps_agent_id_fkey" // ALTER TABLE ONLY workspace_apps ADD CONSTRAINT workspace_apps_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
ForeignKeyWorkspaceBuildParametersWorkspaceBuildID ForeignKeyConstraint = "workspace_build_parameters_workspace_build_id_fkey" // ALTER TABLE ONLY workspace_build_parameters ADD CONSTRAINT workspace_build_parameters_workspace_build_id_fkey FOREIGN KEY (workspace_build_id) REFERENCES workspace_builds(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceBuildsAiTasksSidebarAppID ForeignKeyConstraint = "workspace_builds_ai_tasks_sidebar_app_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_ai_tasks_sidebar_app_id_fkey FOREIGN KEY (ai_tasks_sidebar_app_id) REFERENCES workspace_apps(id);
ForeignKeyWorkspaceBuildsJobID ForeignKeyConstraint = "workspace_builds_job_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
ForeignKeyWorkspaceBuildsTemplateVersionID ForeignKeyConstraint = "workspace_builds_template_version_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
ForeignKeyWorkspaceBuildsTemplateVersionPresetID ForeignKeyConstraint = "workspace_builds_template_version_preset_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_preset_id_fkey FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets(id) ON DELETE SET NULL;
diff --git a/coderd/database/migrations/000335_ai_tasks.down.sql b/coderd/database/migrations/000335_ai_tasks.down.sql
new file mode 100644
index 0000000000000..b4684184b182b
--- /dev/null
+++ b/coderd/database/migrations/000335_ai_tasks.down.sql
@@ -0,0 +1,77 @@
+DROP VIEW workspace_build_with_user;
+
+DROP VIEW template_version_with_user;
+
+DROP INDEX idx_template_versions_has_ai_task;
+
+ALTER TABLE
+ template_versions DROP COLUMN has_ai_task;
+
+ALTER TABLE
+ workspace_builds DROP CONSTRAINT workspace_builds_ai_tasks_sidebar_app_id_fkey;
+
+ALTER TABLE
+ workspace_builds DROP COLUMN ai_tasks_sidebar_app_id;
+
+ALTER TABLE
+ workspace_builds DROP COLUMN has_ai_task;
+
+-- Recreate `workspace_build_with_user` as defined in dump.sql
+CREATE VIEW workspace_build_with_user AS
+SELECT
+ workspace_builds.id,
+ workspace_builds.created_at,
+ workspace_builds.updated_at,
+ workspace_builds.workspace_id,
+ workspace_builds.template_version_id,
+ workspace_builds.build_number,
+ workspace_builds.transition,
+ workspace_builds.initiator_id,
+ workspace_builds.provisioner_state,
+ workspace_builds.job_id,
+ workspace_builds.deadline,
+ workspace_builds.reason,
+ workspace_builds.daily_cost,
+ workspace_builds.max_deadline,
+ workspace_builds.template_version_preset_id,
+ COALESCE(visible_users.avatar_url, '' :: text) AS initiator_by_avatar_url,
+ COALESCE(visible_users.username, '' :: text) AS initiator_by_username,
+ COALESCE(visible_users.name, '' :: text) AS initiator_by_name
+FROM
+ (
+ workspace_builds
+ LEFT JOIN visible_users ON (
+ (workspace_builds.initiator_id = visible_users.id)
+ )
+ );
+
+COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';
+
+-- Recreate `template_version_with_user` as defined in dump.sql
+CREATE VIEW template_version_with_user AS
+SELECT
+ template_versions.id,
+ template_versions.template_id,
+ template_versions.organization_id,
+ template_versions.created_at,
+ template_versions.updated_at,
+ template_versions.name,
+ template_versions.readme,
+ template_versions.job_id,
+ template_versions.created_by,
+ template_versions.external_auth_providers,
+ template_versions.message,
+ template_versions.archived,
+ template_versions.source_example_id,
+ COALESCE(visible_users.avatar_url, '' :: text) AS created_by_avatar_url,
+ COALESCE(visible_users.username, '' :: text) AS created_by_username,
+ COALESCE(visible_users.name, '' :: text) AS created_by_name
+FROM
+ (
+ template_versions
+ LEFT JOIN visible_users ON (
+ (template_versions.created_by = visible_users.id)
+ )
+ );
+
+COMMENT ON VIEW template_version_with_user IS 'Joins in the username + avatar url of the created by user.';
diff --git a/coderd/database/migrations/000335_ai_tasks.up.sql b/coderd/database/migrations/000335_ai_tasks.up.sql
new file mode 100644
index 0000000000000..4aed761b568a5
--- /dev/null
+++ b/coderd/database/migrations/000335_ai_tasks.up.sql
@@ -0,0 +1,103 @@
+-- Determines if a coder_ai_task resource was included in a
+-- workspace build.
+ALTER TABLE
+ workspace_builds
+ADD
+ COLUMN has_ai_task BOOLEAN NOT NULL DEFAULT FALSE;
+
+-- The app that is displayed in the ai tasks sidebar.
+ALTER TABLE
+ workspace_builds
+ADD
+ COLUMN ai_tasks_sidebar_app_id UUID DEFAULT NULL;
+
+ALTER TABLE
+ workspace_builds
+ADD
+ CONSTRAINT workspace_builds_ai_tasks_sidebar_app_id_fkey FOREIGN KEY (ai_tasks_sidebar_app_id) REFERENCES workspace_apps(id);
+
+-- Determines if a coder_ai_task resource is defined in a template version.
+ALTER TABLE
+ template_versions
+ADD
+ COLUMN has_ai_task BOOLEAN NOT NULL DEFAULT FALSE;
+
+-- The Tasks tab will be rendered in the UI only if there's at least one template version with has_ai_task set to true.
+-- The query to determine this will be run on every UI render, and this index speeds it up.
+-- SELECT EXISTS (SELECT 1 FROM template_versions WHERE has_ai_task = TRUE);
+CREATE INDEX idx_template_versions_has_ai_task ON template_versions USING btree (has_ai_task);
+
+DROP VIEW workspace_build_with_user;
+
+-- We're adding the has_ai_task and ai_tasks_sidebar_app_id columns.
+CREATE VIEW workspace_build_with_user AS
+SELECT
+ workspace_builds.id,
+ workspace_builds.created_at,
+ workspace_builds.updated_at,
+ workspace_builds.workspace_id,
+ workspace_builds.template_version_id,
+ workspace_builds.build_number,
+ workspace_builds.transition,
+ workspace_builds.initiator_id,
+ workspace_builds.provisioner_state,
+ workspace_builds.job_id,
+ workspace_builds.deadline,
+ workspace_builds.reason,
+ workspace_builds.daily_cost,
+ workspace_builds.max_deadline,
+ workspace_builds.template_version_preset_id,
+ workspace_builds.has_ai_task,
+ workspace_builds.ai_tasks_sidebar_app_id,
+ COALESCE(
+ visible_users.avatar_url,
+ '' :: text
+ ) AS initiator_by_avatar_url,
+ COALESCE(
+ visible_users.username,
+ '' :: text
+ ) AS initiator_by_username,
+ COALESCE(visible_users.name, '' :: text) AS initiator_by_name
+FROM
+ (
+ workspace_builds
+ LEFT JOIN visible_users ON (
+ (
+ workspace_builds.initiator_id = visible_users.id
+ )
+ )
+ );
+
+COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';
+
+DROP VIEW template_version_with_user;
+
+-- We're adding the has_ai_task column.
+CREATE VIEW template_version_with_user AS
+SELECT
+ template_versions.id,
+ template_versions.template_id,
+ template_versions.organization_id,
+ template_versions.created_at,
+ template_versions.updated_at,
+ template_versions.name,
+ template_versions.readme,
+ template_versions.job_id,
+ template_versions.created_by,
+ template_versions.external_auth_providers,
+ template_versions.message,
+ template_versions.archived,
+ template_versions.source_example_id,
+ template_versions.has_ai_task,
+ COALESCE(visible_users.avatar_url, '' :: text) AS created_by_avatar_url,
+ COALESCE(visible_users.username, '' :: text) AS created_by_username,
+ COALESCE(visible_users.name, '' :: text) AS created_by_name
+FROM
+ (
+ template_versions
+ LEFT JOIN visible_users ON (
+ (template_versions.created_by = visible_users.id)
+ )
+ );
+
+COMMENT ON VIEW template_version_with_user IS 'Joins in the username + avatar url of the created by user.';
diff --git a/coderd/database/models.go b/coderd/database/models.go
index 69ae70b6c3bd3..2533c9a843501 100644
--- a/coderd/database/models.go
+++ b/coderd/database/models.go
@@ -3355,6 +3355,7 @@ type TemplateVersion struct {
Message string `db:"message" json:"message"`
Archived bool `db:"archived" json:"archived"`
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
+ HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
CreatedByAvatarURL string `db:"created_by_avatar_url" json:"created_by_avatar_url"`
CreatedByUsername string `db:"created_by_username" json:"created_by_username"`
CreatedByName string `db:"created_by_name" json:"created_by_name"`
@@ -3431,6 +3432,7 @@ type TemplateVersionTable struct {
Message string `db:"message" json:"message"`
Archived bool `db:"archived" json:"archived"`
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
+ HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
}
type TemplateVersionTerraformValue struct {
@@ -3845,6 +3847,8 @@ type WorkspaceBuild struct {
DailyCost int32 `db:"daily_cost" json:"daily_cost"`
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
+ HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
+ AITasksSidebarAppID uuid.NullUUID `db:"ai_tasks_sidebar_app_id" json:"ai_tasks_sidebar_app_id"`
InitiatorByAvatarUrl string `db:"initiator_by_avatar_url" json:"initiator_by_avatar_url"`
InitiatorByUsername string `db:"initiator_by_username" json:"initiator_by_username"`
InitiatorByName string `db:"initiator_by_name" json:"initiator_by_name"`
@@ -3874,6 +3878,8 @@ type WorkspaceBuildTable struct {
DailyCost int32 `db:"daily_cost" json:"daily_cost"`
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
+ HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
+ AITasksSidebarAppID uuid.NullUUID `db:"ai_tasks_sidebar_app_id" json:"ai_tasks_sidebar_app_id"`
}
type WorkspaceLatestBuild struct {
diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go
index eec91c7586d61..92c912a55705a 100644
--- a/coderd/database/queries.sql.go
+++ b/coderd/database/queries.sql.go
@@ -11349,7 +11349,7 @@ FROM
-- Scope an archive to a single template and ignore already archived template versions
(
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task
FROM
template_versions
WHERE
@@ -11450,7 +11450,7 @@ func (q *sqlQuerier) ArchiveUnusedTemplateVersions(ctx context.Context, arg Arch
const getPreviousTemplateVersion = `-- name: GetPreviousTemplateVersion :one
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -11488,6 +11488,7 @@ func (q *sqlQuerier) GetPreviousTemplateVersion(ctx context.Context, arg GetPrev
&i.Message,
&i.Archived,
&i.SourceExampleID,
+ &i.HasAITask,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.CreatedByName,
@@ -11497,7 +11498,7 @@ func (q *sqlQuerier) GetPreviousTemplateVersion(ctx context.Context, arg GetPrev
const getTemplateVersionByID = `-- name: GetTemplateVersionByID :one
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -11521,6 +11522,7 @@ func (q *sqlQuerier) GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (
&i.Message,
&i.Archived,
&i.SourceExampleID,
+ &i.HasAITask,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.CreatedByName,
@@ -11530,7 +11532,7 @@ func (q *sqlQuerier) GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (
const getTemplateVersionByJobID = `-- name: GetTemplateVersionByJobID :one
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -11554,6 +11556,7 @@ func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.U
&i.Message,
&i.Archived,
&i.SourceExampleID,
+ &i.HasAITask,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.CreatedByName,
@@ -11563,7 +11566,7 @@ func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.U
const getTemplateVersionByTemplateIDAndName = `-- name: GetTemplateVersionByTemplateIDAndName :one
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -11593,6 +11596,7 @@ func (q *sqlQuerier) GetTemplateVersionByTemplateIDAndName(ctx context.Context,
&i.Message,
&i.Archived,
&i.SourceExampleID,
+ &i.HasAITask,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.CreatedByName,
@@ -11602,7 +11606,7 @@ func (q *sqlQuerier) GetTemplateVersionByTemplateIDAndName(ctx context.Context,
const getTemplateVersionsByIDs = `-- name: GetTemplateVersionsByIDs :many
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -11632,6 +11636,7 @@ func (q *sqlQuerier) GetTemplateVersionsByIDs(ctx context.Context, ids []uuid.UU
&i.Message,
&i.Archived,
&i.SourceExampleID,
+ &i.HasAITask,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.CreatedByName,
@@ -11651,7 +11656,7 @@ func (q *sqlQuerier) GetTemplateVersionsByIDs(ctx context.Context, ids []uuid.UU
const getTemplateVersionsByTemplateID = `-- name: GetTemplateVersionsByTemplateID :many
SELECT
- id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, created_by_avatar_url, created_by_username, created_by_name
+ id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, created_by_avatar_url, created_by_username, created_by_name
FROM
template_version_with_user AS template_versions
WHERE
@@ -11728,6 +11733,7 @@ func (q *sqlQuerier) GetTemplateVersionsByTemplateID(ctx context.Context, arg Ge
&i.Message,
&i.Archived,
&i.SourceExampleID,
+ &i.HasAITask,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.CreatedByName,
@@ -11746,7 +11752,7 @@ func (q *sqlQuerier) GetTemplateVersionsByTemplateID(ctx context.Context, arg Ge
}
const getTemplateVersionsCreatedAfter = `-- name: GetTemplateVersionsCreatedAfter :many
-SELECT id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, created_by_avatar_url, created_by_username, created_by_name FROM template_version_with_user AS template_versions WHERE created_at > $1
+SELECT id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id, has_ai_task, created_by_avatar_url, created_by_username, created_by_name FROM template_version_with_user AS template_versions WHERE created_at > $1
`
func (q *sqlQuerier) GetTemplateVersionsCreatedAfter(ctx context.Context, createdAt time.Time) ([]TemplateVersion, error) {
@@ -11772,6 +11778,7 @@ func (q *sqlQuerier) GetTemplateVersionsCreatedAfter(ctx context.Context, create
&i.Message,
&i.Archived,
&i.SourceExampleID,
+ &i.HasAITask,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.CreatedByName,
@@ -14178,7 +14185,7 @@ const getWorkspaceAgentAndLatestBuildByAuthToken = `-- name: GetWorkspaceAgentAn
SELECT
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite, workspaces.next_start_at,
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version, workspace_agents.display_order, workspace_agents.parent_id, workspace_agents.api_key_scope,
- workspace_build_with_user.id, workspace_build_with_user.created_at, workspace_build_with_user.updated_at, workspace_build_with_user.workspace_id, workspace_build_with_user.template_version_id, workspace_build_with_user.build_number, workspace_build_with_user.transition, workspace_build_with_user.initiator_id, workspace_build_with_user.provisioner_state, workspace_build_with_user.job_id, workspace_build_with_user.deadline, workspace_build_with_user.reason, workspace_build_with_user.daily_cost, workspace_build_with_user.max_deadline, workspace_build_with_user.template_version_preset_id, workspace_build_with_user.initiator_by_avatar_url, workspace_build_with_user.initiator_by_username, workspace_build_with_user.initiator_by_name
+ workspace_build_with_user.id, workspace_build_with_user.created_at, workspace_build_with_user.updated_at, workspace_build_with_user.workspace_id, workspace_build_with_user.template_version_id, workspace_build_with_user.build_number, workspace_build_with_user.transition, workspace_build_with_user.initiator_id, workspace_build_with_user.provisioner_state, workspace_build_with_user.job_id, workspace_build_with_user.deadline, workspace_build_with_user.reason, workspace_build_with_user.daily_cost, workspace_build_with_user.max_deadline, workspace_build_with_user.template_version_preset_id, workspace_build_with_user.has_ai_task, workspace_build_with_user.ai_tasks_sidebar_app_id, workspace_build_with_user.initiator_by_avatar_url, workspace_build_with_user.initiator_by_username, workspace_build_with_user.initiator_by_name
FROM
workspace_agents
JOIN
@@ -14284,6 +14291,8 @@ func (q *sqlQuerier) GetWorkspaceAgentAndLatestBuildByAuthToken(ctx context.Cont
&i.WorkspaceBuild.DailyCost,
&i.WorkspaceBuild.MaxDeadline,
&i.WorkspaceBuild.TemplateVersionPresetID,
+ &i.WorkspaceBuild.HasAITask,
+ &i.WorkspaceBuild.AITasksSidebarAppID,
&i.WorkspaceBuild.InitiatorByAvatarUrl,
&i.WorkspaceBuild.InitiatorByUsername,
&i.WorkspaceBuild.InitiatorByName,
@@ -16853,7 +16862,7 @@ func (q *sqlQuerier) InsertWorkspaceBuildParameters(ctx context.Context, arg Ins
}
const getActiveWorkspaceBuildsByTemplateID = `-- name: GetActiveWorkspaceBuildsByTemplateID :many
-SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.initiator_by_avatar_url, wb.initiator_by_username, wb.initiator_by_name
+SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.has_ai_task, wb.ai_tasks_sidebar_app_id, wb.initiator_by_avatar_url, wb.initiator_by_username, wb.initiator_by_name
FROM (
SELECT
workspace_id, MAX(build_number) as max_build_number
@@ -16908,6 +16917,8 @@ func (q *sqlQuerier) GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, t
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17007,7 +17018,7 @@ func (q *sqlQuerier) GetFailedWorkspaceBuildsByTemplateID(ctx context.Context, a
const getLatestWorkspaceBuildByWorkspaceID = `-- name: GetLatestWorkspaceBuildByWorkspaceID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, ai_tasks_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17037,6 +17048,8 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17045,7 +17058,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w
}
const getLatestWorkspaceBuilds = `-- name: GetLatestWorkspaceBuilds :many
-SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.initiator_by_avatar_url, wb.initiator_by_username, wb.initiator_by_name
+SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.has_ai_task, wb.ai_tasks_sidebar_app_id, wb.initiator_by_avatar_url, wb.initiator_by_username, wb.initiator_by_name
FROM (
SELECT
workspace_id, MAX(build_number) as max_build_number
@@ -17084,6 +17097,8 @@ func (q *sqlQuerier) GetLatestWorkspaceBuilds(ctx context.Context) ([]WorkspaceB
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17102,7 +17117,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuilds(ctx context.Context) ([]WorkspaceB
}
const getLatestWorkspaceBuildsByWorkspaceIDs = `-- name: GetLatestWorkspaceBuildsByWorkspaceIDs :many
-SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.initiator_by_avatar_url, wb.initiator_by_username, wb.initiator_by_name
+SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.has_ai_task, wb.ai_tasks_sidebar_app_id, wb.initiator_by_avatar_url, wb.initiator_by_username, wb.initiator_by_name
FROM (
SELECT
workspace_id, MAX(build_number) as max_build_number
@@ -17143,6 +17158,8 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context,
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17162,7 +17179,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context,
const getWorkspaceBuildByID = `-- name: GetWorkspaceBuildByID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, ai_tasks_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17190,6 +17207,8 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17199,7 +17218,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
const getWorkspaceBuildByJobID = `-- name: GetWorkspaceBuildByJobID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, ai_tasks_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17227,6 +17246,8 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17236,7 +17257,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
const getWorkspaceBuildByWorkspaceIDAndBuildNumber = `-- name: GetWorkspaceBuildByWorkspaceIDAndBuildNumber :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, ai_tasks_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17268,6 +17289,8 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Co
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17344,7 +17367,7 @@ func (q *sqlQuerier) GetWorkspaceBuildStatsByTemplates(ctx context.Context, sinc
const getWorkspaceBuildsByWorkspaceID = `-- name: GetWorkspaceBuildsByWorkspaceID :many
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, ai_tasks_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17415,6 +17438,8 @@ func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceID(ctx context.Context, arg Ge
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17433,7 +17458,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceID(ctx context.Context, arg Ge
}
const getWorkspaceBuildsCreatedAfter = `-- name: GetWorkspaceBuildsCreatedAfter :many
-SELECT id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name FROM workspace_build_with_user WHERE created_at > $1
+SELECT id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, has_ai_task, ai_tasks_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name FROM workspace_build_with_user WHERE created_at > $1
`
func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceBuild, error) {
@@ -17461,6 +17486,8 @@ func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, created
&i.DailyCost,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
+ &i.HasAITask,
+ &i.AITasksSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
diff --git a/coderd/database/sqlc.yaml b/coderd/database/sqlc.yaml
index b43281a3f1051..79b4b21f4d83f 100644
--- a/coderd/database/sqlc.yaml
+++ b/coderd/database/sqlc.yaml
@@ -147,6 +147,8 @@ sql:
crypto_key_feature_workspace_apps_api_key: CryptoKeyFeatureWorkspaceAppsAPIKey
crypto_key_feature_oidc_convert: CryptoKeyFeatureOIDCConvert
stale_interval_ms: StaleIntervalMS
+ has_ai_task: HasAITask
+ ai_tasks_sidebar_app_id: AITasksSidebarAppID
rules:
- name: do-not-use-public-schema-in-queries
message: "do not use public schema in queries"
diff --git a/docs/admin/security/audit-logs.md b/docs/admin/security/audit-logs.md
index 4ed07cdc9dfb6..080e864fcb866 100644
--- a/docs/admin/security/audit-logs.md
+++ b/docs/admin/security/audit-logs.md
@@ -27,11 +27,11 @@ We track the following resources:
| OrganizationSyncSettings
|
Field | Tracked |
| assign_default | true |
field | true |
mapping | true |
|
| RoleSyncSettings
| Field | Tracked |
| field | true |
mapping | true |
|
| Template
write, delete | Field | Tracked |
| active_version_id | true |
activity_bump | true |
allow_user_autostart | true |
allow_user_autostop | true |
allow_user_cancel_workspace_jobs | true |
autostart_block_days_of_week | true |
autostop_requirement_days_of_week | true |
autostop_requirement_weeks | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_name | false |
created_by_username | false |
default_ttl | true |
deleted | false |
deprecated | true |
description | true |
display_name | true |
failure_ttl | true |
group_acl | true |
icon | true |
id | true |
max_port_sharing_level | true |
name | true |
organization_display_name | false |
organization_icon | false |
organization_id | false |
organization_name | false |
provisioner | true |
require_active_version | true |
time_til_dormant | true |
time_til_dormant_autodelete | true |
updated_at | false |
use_classic_parameter_flow | true |
user_acl | true |
|
-| TemplateVersion
create, write | Field | Tracked |
| archived | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_name | false |
created_by_username | false |
external_auth_providers | false |
id | true |
job_id | false |
message | false |
name | true |
organization_id | false |
readme | true |
source_example_id | false |
template_id | true |
updated_at | false |
|
+| TemplateVersion
create, write | Field | Tracked |
| archived | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_name | false |
created_by_username | false |
external_auth_providers | false |
has_ai_task | false |
id | true |
job_id | false |
message | false |
name | true |
organization_id | false |
readme | true |
source_example_id | false |
template_id | true |
updated_at | false |
|
| User
create, write, delete | Field | Tracked |
| avatar_url | false |
created_at | false |
deleted | true |
email | true |
github_com_user_id | false |
hashed_one_time_passcode | false |
hashed_password | true |
id | true |
is_system | true |
last_seen_at | false |
login_type | true |
name | true |
one_time_passcode_expires_at | true |
quiet_hours_schedule | true |
rbac_roles | true |
status | true |
updated_at | false |
username | true |
|
| WorkspaceAgent
connect, disconnect | Field | Tracked |
| api_key_scope | false |
api_version | false |
architecture | false |
auth_instance_id | false |
auth_token | false |
connection_timeout_seconds | false |
created_at | false |
directory | false |
disconnected_at | false |
display_apps | false |
display_order | false |
environment_variables | false |
expanded_directory | false |
first_connected_at | false |
id | false |
instance_metadata | false |
last_connected_at | false |
last_connected_replica_id | false |
lifecycle_state | false |
logs_length | false |
logs_overflowed | false |
motd_file | false |
name | false |
operating_system | false |
parent_id | false |
ready_at | false |
resource_id | false |
resource_metadata | false |
started_at | false |
subsystems | false |
troubleshooting_url | false |
updated_at | false |
version | false |
|
| WorkspaceApp
open, close | Field | Tracked |
| agent_id | false |
command | false |
created_at | false |
display_group | false |
display_name | false |
display_order | false |
external | false |
health | false |
healthcheck_interval | false |
healthcheck_threshold | false |
healthcheck_url | false |
hidden | false |
icon | false |
id | false |
open_in | false |
sharing_level | false |
slug | false |
subdomain | false |
url | false |
|
-| WorkspaceBuild
start, stop | Field | Tracked |
| build_number | false |
created_at | false |
daily_cost | false |
deadline | false |
id | false |
initiator_by_avatar_url | false |
initiator_by_name | false |
initiator_by_username | false |
initiator_id | false |
job_id | false |
max_deadline | false |
provisioner_state | false |
reason | false |
template_version_id | true |
template_version_preset_id | false |
transition | false |
updated_at | false |
workspace_id | false |
|
+| WorkspaceBuild
start, stop | Field | Tracked |
| ai_tasks_sidebar_app_id | false |
build_number | false |
created_at | false |
daily_cost | false |
deadline | false |
has_ai_task | false |
id | false |
initiator_by_avatar_url | false |
initiator_by_name | false |
initiator_by_username | false |
initiator_id | false |
job_id | false |
max_deadline | false |
provisioner_state | false |
reason | false |
template_version_id | true |
template_version_preset_id | false |
transition | false |
updated_at | false |
workspace_id | false |
|
| WorkspaceProxy
| Field | Tracked |
| created_at | true |
deleted | false |
derp_enabled | true |
derp_only | true |
display_name | true |
icon | true |
id | true |
name | true |
region_id | true |
token_hashed_secret | true |
updated_at | false |
url | true |
version | true |
wildcard_hostname | true |
|
| WorkspaceTable
| Field | Tracked |
| automatic_updates | true |
autostart_schedule | true |
created_at | false |
deleted | false |
deleting_at | true |
dormant_at | true |
favorite | true |
id | true |
last_used_at | false |
name | true |
next_start_at | true |
organization_id | false |
owner_id | true |
template_id | true |
ttl | true |
updated_at | false |
|
diff --git a/enterprise/audit/table.go b/enterprise/audit/table.go
index d52632996ba26..ffb79810ee2c3 100644
--- a/enterprise/audit/table.go
+++ b/enterprise/audit/table.go
@@ -135,6 +135,7 @@ var auditableResourcesTypes = map[any]map[string]Action{
"created_by_name": ActionIgnore,
"archived": ActionTrack,
"source_example_id": ActionIgnore, // Never changes.
+ "has_ai_task": ActionIgnore, // Never changes.
},
&database.User{}: {
"id": ActionTrack,
@@ -193,6 +194,8 @@ var auditableResourcesTypes = map[any]map[string]Action{
"initiator_by_username": ActionIgnore,
"initiator_by_name": ActionIgnore,
"template_version_preset_id": ActionIgnore, // Never changes.
+ "has_ai_task": ActionIgnore, // Never changes.
+ "ai_tasks_sidebar_app_id": ActionIgnore, // Never changes.
},
&database.AuditableGroup{}: {
"id": ActionTrack,
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy