diff --git a/cli/testdata/coder_list_--output_json.golden b/cli/testdata/coder_list_--output_json.golden
index 5304f2ce262ee..e97894c4afb21 100644
--- a/cli/testdata/coder_list_--output_json.golden
+++ b/cli/testdata/coder_list_--output_json.golden
@@ -68,7 +68,8 @@
"available": 0,
"most_recently_seen": null
},
- "template_version_preset_id": null
+ "template_version_preset_id": null,
+ "has_ai_task": false
},
"latest_app_status": null,
"outdated": false,
diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go
index 3c6f691616d52..86279bcb41bb6 100644
--- a/coderd/database/dbauthz/dbauthz.go
+++ b/coderd/database/dbauthz/dbauthz.go
@@ -4518,6 +4518,28 @@ func (q *querier) UpdateTemplateScheduleByID(ctx context.Context, arg database.U
return update(q.log, q.auth, fetch, q.db.UpdateTemplateScheduleByID)(ctx, arg)
}
+func (q *querier) UpdateTemplateVersionAITaskByJobID(ctx context.Context, arg database.UpdateTemplateVersionAITaskByJobIDParams) error {
+ // An actor is allowed to update the template version AI task flag if they are authorized to update the template.
+ tv, err := q.db.GetTemplateVersionByJobID(ctx, arg.JobID)
+ if err != nil {
+ return err
+ }
+ var obj rbac.Objecter
+ if !tv.TemplateID.Valid {
+ obj = rbac.ResourceTemplate.InOrg(tv.OrganizationID)
+ } else {
+ tpl, err := q.db.GetTemplateByID(ctx, tv.TemplateID.UUID)
+ if err != nil {
+ return err
+ }
+ obj = tpl
+ }
+ if err := q.authorizeContext(ctx, policy.ActionUpdate, obj); err != nil {
+ return err
+ }
+ return q.db.UpdateTemplateVersionAITaskByJobID(ctx, arg)
+}
+
func (q *querier) UpdateTemplateVersionByID(ctx context.Context, arg database.UpdateTemplateVersionByIDParams) error {
// An actor is allowed to update the template version if they are authorized to update the template.
tv, err := q.db.GetTemplateVersionByID(ctx, arg.ID)
@@ -4874,6 +4896,24 @@ func (q *querier) UpdateWorkspaceAutostart(ctx context.Context, arg database.Upd
return update(q.log, q.auth, fetch, q.db.UpdateWorkspaceAutostart)(ctx, arg)
}
+func (q *querier) UpdateWorkspaceBuildAITaskByID(ctx context.Context, arg database.UpdateWorkspaceBuildAITaskByIDParams) error {
+ build, err := q.db.GetWorkspaceBuildByID(ctx, arg.ID)
+ if err != nil {
+ return err
+ }
+
+ workspace, err := q.db.GetWorkspaceByID(ctx, build.WorkspaceID)
+ if err != nil {
+ return err
+ }
+
+ err = q.authorizeContext(ctx, policy.ActionUpdate, workspace.RBACObject())
+ if err != nil {
+ return err
+ }
+ return q.db.UpdateWorkspaceBuildAITaskByID(ctx, arg)
+}
+
// UpdateWorkspaceBuildCostByID is used by the provisioning system to update the cost of a workspace build.
func (q *querier) UpdateWorkspaceBuildCostByID(ctx context.Context, arg database.UpdateWorkspaceBuildCostByIDParams) error {
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceSystem); err != nil {
diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go
index f5077b7bdcda9..a07682a971fa5 100644
--- a/coderd/database/dbauthz/dbauthz_test.go
+++ b/coderd/database/dbauthz/dbauthz_test.go
@@ -1391,6 +1391,24 @@ func (s *MethodTestSuite) TestTemplate() {
ID: t1.ID,
}).Asserts(t1, policy.ActionUpdate)
}))
+ s.Run("UpdateTemplateVersionAITaskByJobID", s.Subtest(func(db database.Store, check *expects) {
+ dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
+ o := dbgen.Organization(s.T(), db, database.Organization{})
+ u := dbgen.User(s.T(), db, database.User{})
+ _ = dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{OrganizationID: o.ID, UserID: u.ID})
+ t := dbgen.Template(s.T(), db, database.Template{OrganizationID: o.ID, CreatedBy: u.ID})
+ job := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{OrganizationID: o.ID})
+ _ = dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
+ OrganizationID: o.ID,
+ CreatedBy: u.ID,
+ JobID: job.ID,
+ TemplateID: uuid.NullUUID{UUID: t.ID, Valid: true},
+ })
+ check.Args(database.UpdateTemplateVersionAITaskByJobIDParams{
+ JobID: job.ID,
+ HasAITask: sql.NullBool{Bool: true, Valid: true},
+ }).Asserts(t, policy.ActionUpdate)
+ }))
s.Run("UpdateTemplateWorkspacesLastUsedAt", s.Subtest(func(db database.Store, check *expects) {
dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
t1 := dbgen.Template(s.T(), db, database.Template{})
@@ -3050,6 +3068,40 @@ func (s *MethodTestSuite) TestWorkspace() {
Deadline: b.Deadline,
}).Asserts(w, policy.ActionUpdate)
}))
+ s.Run("UpdateWorkspaceBuildAITaskByID", s.Subtest(func(db database.Store, check *expects) {
+ u := dbgen.User(s.T(), db, database.User{})
+ o := dbgen.Organization(s.T(), db, database.Organization{})
+ tpl := dbgen.Template(s.T(), db, database.Template{
+ OrganizationID: o.ID,
+ CreatedBy: u.ID,
+ })
+ tv := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
+ TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true},
+ OrganizationID: o.ID,
+ CreatedBy: u.ID,
+ })
+ w := dbgen.Workspace(s.T(), db, database.WorkspaceTable{
+ TemplateID: tpl.ID,
+ OrganizationID: o.ID,
+ OwnerID: u.ID,
+ })
+ j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
+ Type: database.ProvisionerJobTypeWorkspaceBuild,
+ })
+ b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{
+ JobID: j.ID,
+ WorkspaceID: w.ID,
+ TemplateVersionID: tv.ID,
+ })
+ res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: b.JobID})
+ agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
+ app := dbgen.WorkspaceApp(s.T(), db, database.WorkspaceApp{AgentID: agt.ID})
+ check.Args(database.UpdateWorkspaceBuildAITaskByIDParams{
+ HasAITask: sql.NullBool{Bool: true, Valid: true},
+ SidebarAppID: uuid.NullUUID{UUID: app.ID, Valid: true},
+ ID: b.ID,
+ }).Asserts(w, policy.ActionUpdate)
+ }))
s.Run("SoftDeleteWorkspaceByID", s.Subtest(func(db database.Store, check *expects) {
u := dbgen.User(s.T(), db, database.User{})
o := dbgen.Organization(s.T(), db, database.Organization{})
diff --git a/coderd/database/dbgen/dbgen.go b/coderd/database/dbgen/dbgen.go
index 06ff262bd4e63..2be9c28f1cc47 100644
--- a/coderd/database/dbgen/dbgen.go
+++ b/coderd/database/dbgen/dbgen.go
@@ -390,6 +390,9 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
t.Helper()
buildID := takeFirst(orig.ID, uuid.New())
+ jobID := takeFirst(orig.JobID, uuid.New())
+ hasAITask := takeFirst(orig.HasAITask, sql.NullBool{})
+ sidebarAppID := takeFirst(orig.AITaskSidebarAppID, uuid.NullUUID{})
var build database.WorkspaceBuild
err := db.InTx(func(db database.Store) error {
err := db.InsertWorkspaceBuild(genCtx, database.InsertWorkspaceBuildParams{
@@ -401,7 +404,7 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
BuildNumber: takeFirst(orig.BuildNumber, 1),
Transition: takeFirst(orig.Transition, database.WorkspaceTransitionStart),
InitiatorID: takeFirst(orig.InitiatorID, uuid.New()),
- JobID: takeFirst(orig.JobID, uuid.New()),
+ JobID: jobID,
ProvisionerState: takeFirstSlice(orig.ProvisionerState, []byte{}),
Deadline: takeFirst(orig.Deadline, dbtime.Now().Add(time.Hour)),
MaxDeadline: takeFirst(orig.MaxDeadline, time.Time{}),
@@ -410,7 +413,6 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
UUID: uuid.UUID{},
Valid: false,
}),
- HasAITask: orig.HasAITask,
})
if err != nil {
return err
@@ -424,6 +426,15 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
require.NoError(t, err)
}
+ if hasAITask.Valid {
+ require.NoError(t, db.UpdateWorkspaceBuildAITaskByID(genCtx, database.UpdateWorkspaceBuildAITaskByIDParams{
+ HasAITask: hasAITask,
+ SidebarAppID: sidebarAppID,
+ UpdatedAt: dbtime.Now(),
+ ID: buildID,
+ }))
+ }
+
build, err = db.GetWorkspaceBuildByID(genCtx, buildID)
if err != nil {
return err
@@ -971,6 +982,8 @@ func ExternalAuthLink(t testing.TB, db database.Store, orig database.ExternalAut
func TemplateVersion(t testing.TB, db database.Store, orig database.TemplateVersion) database.TemplateVersion {
var version database.TemplateVersion
+ hasAITask := takeFirst(orig.HasAITask, sql.NullBool{})
+ jobID := takeFirst(orig.JobID, uuid.New())
err := db.InTx(func(db database.Store) error {
versionID := takeFirst(orig.ID, uuid.New())
err := db.InsertTemplateVersion(genCtx, database.InsertTemplateVersionParams{
@@ -982,15 +995,22 @@ func TemplateVersion(t testing.TB, db database.Store, orig database.TemplateVers
Name: takeFirst(orig.Name, testutil.GetRandomName(t)),
Message: orig.Message,
Readme: takeFirst(orig.Readme, testutil.GetRandomName(t)),
- JobID: takeFirst(orig.JobID, uuid.New()),
+ JobID: jobID,
CreatedBy: takeFirst(orig.CreatedBy, uuid.New()),
SourceExampleID: takeFirst(orig.SourceExampleID, sql.NullString{}),
- HasAITask: orig.HasAITask,
})
if err != nil {
return err
}
+ if hasAITask.Valid {
+ require.NoError(t, db.UpdateTemplateVersionAITaskByJobID(genCtx, database.UpdateTemplateVersionAITaskByJobIDParams{
+ JobID: jobID,
+ HasAITask: hasAITask,
+ UpdatedAt: dbtime.Now(),
+ }))
+ }
+
version, err = db.GetTemplateVersionByID(genCtx, versionID)
if err != nil {
return err
diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go
index 8969a16a9c4ff..8d14b2504b9ff 100644
--- a/coderd/database/dbmem/dbmem.go
+++ b/coderd/database/dbmem/dbmem.go
@@ -9465,7 +9465,6 @@ func (q *FakeQuerier) InsertTemplateVersion(_ context.Context, arg database.Inse
JobID: arg.JobID,
CreatedBy: arg.CreatedBy,
SourceExampleID: arg.SourceExampleID,
- HasAITask: arg.HasAITask,
}
q.templateVersions = append(q.templateVersions, version)
return nil
@@ -10103,7 +10102,6 @@ func (q *FakeQuerier) InsertWorkspaceBuild(_ context.Context, arg database.Inser
MaxDeadline: arg.MaxDeadline,
Reason: arg.Reason,
TemplateVersionPresetID: arg.TemplateVersionPresetID,
- HasAITask: arg.HasAITask,
}
q.workspaceBuilds = append(q.workspaceBuilds, workspaceBuild)
return nil
@@ -11308,6 +11306,26 @@ func (q *FakeQuerier) UpdateTemplateScheduleByID(_ context.Context, arg database
return sql.ErrNoRows
}
+func (q *FakeQuerier) UpdateTemplateVersionAITaskByJobID(_ context.Context, arg database.UpdateTemplateVersionAITaskByJobIDParams) error {
+ if err := validateDatabaseType(arg); err != nil {
+ return err
+ }
+
+ q.mutex.Lock()
+ defer q.mutex.Unlock()
+
+ for index, templateVersion := range q.templateVersions {
+ if templateVersion.JobID != arg.JobID {
+ continue
+ }
+ templateVersion.HasAITask = arg.HasAITask
+ templateVersion.UpdatedAt = arg.UpdatedAt
+ q.templateVersions[index] = templateVersion
+ return nil
+ }
+ return sql.ErrNoRows
+}
+
func (q *FakeQuerier) UpdateTemplateVersionByID(_ context.Context, arg database.UpdateTemplateVersionByIDParams) error {
if err := validateDatabaseType(arg); err != nil {
return err
@@ -12003,6 +12021,35 @@ func (q *FakeQuerier) UpdateWorkspaceAutostart(_ context.Context, arg database.U
return sql.ErrNoRows
}
+func (q *FakeQuerier) UpdateWorkspaceBuildAITaskByID(_ context.Context, arg database.UpdateWorkspaceBuildAITaskByIDParams) error {
+ if arg.HasAITask.Bool && !arg.SidebarAppID.Valid {
+ return xerrors.Errorf("ai_task_sidebar_app_id is required when has_ai_task is true")
+ }
+ if !arg.HasAITask.Valid && arg.SidebarAppID.Valid {
+ return xerrors.Errorf("ai_task_sidebar_app_id is can only be set when has_ai_task is true")
+ }
+
+ err := validateDatabaseType(arg)
+ if err != nil {
+ return err
+ }
+
+ q.mutex.Lock()
+ defer q.mutex.Unlock()
+
+ for index, workspaceBuild := range q.workspaceBuilds {
+ if workspaceBuild.ID != arg.ID {
+ continue
+ }
+ workspaceBuild.HasAITask = arg.HasAITask
+ workspaceBuild.AITaskSidebarAppID = arg.SidebarAppID
+ workspaceBuild.UpdatedAt = dbtime.Now()
+ q.workspaceBuilds[index] = workspaceBuild
+ return nil
+ }
+ return sql.ErrNoRows
+}
+
func (q *FakeQuerier) UpdateWorkspaceBuildCostByID(_ context.Context, arg database.UpdateWorkspaceBuildCostByIDParams) error {
if err := validateDatabaseType(arg); err != nil {
return err
diff --git a/coderd/database/dbmetrics/querymetrics.go b/coderd/database/dbmetrics/querymetrics.go
index 3a5bfac1ae57b..fb68f9c7ab5e3 100644
--- a/coderd/database/dbmetrics/querymetrics.go
+++ b/coderd/database/dbmetrics/querymetrics.go
@@ -2825,6 +2825,13 @@ func (m queryMetricsStore) UpdateTemplateScheduleByID(ctx context.Context, arg d
return err
}
+func (m queryMetricsStore) UpdateTemplateVersionAITaskByJobID(ctx context.Context, arg database.UpdateTemplateVersionAITaskByJobIDParams) error {
+ start := time.Now()
+ r0 := m.s.UpdateTemplateVersionAITaskByJobID(ctx, arg)
+ m.queryLatencies.WithLabelValues("UpdateTemplateVersionAITaskByJobID").Observe(time.Since(start).Seconds())
+ return r0
+}
+
func (m queryMetricsStore) UpdateTemplateVersionByID(ctx context.Context, arg database.UpdateTemplateVersionByIDParams) error {
start := time.Now()
err := m.s.UpdateTemplateVersionByID(ctx, arg)
@@ -3028,6 +3035,13 @@ func (m queryMetricsStore) UpdateWorkspaceAutostart(ctx context.Context, arg dat
return err
}
+func (m queryMetricsStore) UpdateWorkspaceBuildAITaskByID(ctx context.Context, arg database.UpdateWorkspaceBuildAITaskByIDParams) error {
+ start := time.Now()
+ r0 := m.s.UpdateWorkspaceBuildAITaskByID(ctx, arg)
+ m.queryLatencies.WithLabelValues("UpdateWorkspaceBuildAITaskByID").Observe(time.Since(start).Seconds())
+ return r0
+}
+
func (m queryMetricsStore) UpdateWorkspaceBuildCostByID(ctx context.Context, arg database.UpdateWorkspaceBuildCostByIDParams) error {
start := time.Now()
err := m.s.UpdateWorkspaceBuildCostByID(ctx, arg)
diff --git a/coderd/database/dbmock/dbmock.go b/coderd/database/dbmock/dbmock.go
index 067ad062e1dd8..717dc8ef193d1 100644
--- a/coderd/database/dbmock/dbmock.go
+++ b/coderd/database/dbmock/dbmock.go
@@ -5977,6 +5977,20 @@ func (mr *MockStoreMockRecorder) UpdateTemplateScheduleByID(ctx, arg any) *gomoc
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTemplateScheduleByID", reflect.TypeOf((*MockStore)(nil).UpdateTemplateScheduleByID), ctx, arg)
}
+// UpdateTemplateVersionAITaskByJobID mocks base method.
+func (m *MockStore) UpdateTemplateVersionAITaskByJobID(ctx context.Context, arg database.UpdateTemplateVersionAITaskByJobIDParams) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "UpdateTemplateVersionAITaskByJobID", ctx, arg)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// UpdateTemplateVersionAITaskByJobID indicates an expected call of UpdateTemplateVersionAITaskByJobID.
+func (mr *MockStoreMockRecorder) UpdateTemplateVersionAITaskByJobID(ctx, arg any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTemplateVersionAITaskByJobID", reflect.TypeOf((*MockStore)(nil).UpdateTemplateVersionAITaskByJobID), ctx, arg)
+}
+
// UpdateTemplateVersionByID mocks base method.
func (m *MockStore) UpdateTemplateVersionByID(ctx context.Context, arg database.UpdateTemplateVersionByIDParams) error {
m.ctrl.T.Helper()
@@ -6395,6 +6409,20 @@ func (mr *MockStoreMockRecorder) UpdateWorkspaceAutostart(ctx, arg any) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspaceAutostart", reflect.TypeOf((*MockStore)(nil).UpdateWorkspaceAutostart), ctx, arg)
}
+// UpdateWorkspaceBuildAITaskByID mocks base method.
+func (m *MockStore) UpdateWorkspaceBuildAITaskByID(ctx context.Context, arg database.UpdateWorkspaceBuildAITaskByIDParams) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "UpdateWorkspaceBuildAITaskByID", ctx, arg)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// UpdateWorkspaceBuildAITaskByID indicates an expected call of UpdateWorkspaceBuildAITaskByID.
+func (mr *MockStoreMockRecorder) UpdateWorkspaceBuildAITaskByID(ctx, arg any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspaceBuildAITaskByID", reflect.TypeOf((*MockStore)(nil).UpdateWorkspaceBuildAITaskByID), ctx, arg)
+}
+
// UpdateWorkspaceBuildCostByID mocks base method.
func (m *MockStore) UpdateWorkspaceBuildCostByID(ctx context.Context, arg database.UpdateWorkspaceBuildCostByIDParams) error {
m.ctrl.T.Helper()
diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql
index 133bb1cd37da3..522f24537e576 100644
--- a/coderd/database/dump.sql
+++ b/coderd/database/dump.sql
@@ -2099,7 +2099,8 @@ CREATE TABLE workspace_builds (
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,
has_ai_task boolean,
- ai_tasks_sidebar_app_id uuid
+ ai_task_sidebar_app_id uuid,
+ CONSTRAINT workspace_builds_ai_task_sidebar_app_id_required CHECK (((((has_ai_task IS NULL) OR (has_ai_task = false)) AND (ai_task_sidebar_app_id IS NULL)) OR ((has_ai_task = true) AND (ai_task_sidebar_app_id IS NOT NULL))))
);
CREATE VIEW workspace_build_with_user AS
@@ -2119,7 +2120,7 @@ CREATE VIEW workspace_build_with_user AS
workspace_builds.max_deadline,
workspace_builds.template_version_preset_id,
workspace_builds.has_ai_task,
- workspace_builds.ai_tasks_sidebar_app_id,
+ workspace_builds.ai_task_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
@@ -3095,7 +3096,7 @@ 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);
+ ADD CONSTRAINT workspace_builds_ai_task_sidebar_app_id_fkey FOREIGN KEY (ai_task_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 ea1ffaf4c8064..c0720bcb5fcdd 100644
--- a/coderd/database/foreign_key_constraint.go
+++ b/coderd/database/foreign_key_constraint.go
@@ -83,7 +83,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);
+ ForeignKeyWorkspaceBuildsAiTaskSidebarAppID ForeignKeyConstraint = "workspace_builds_ai_task_sidebar_app_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_ai_task_sidebar_app_id_fkey FOREIGN KEY (ai_task_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/000342_ai_task_sidebar_app_id_column_and_constraint.down.sql b/coderd/database/migrations/000342_ai_task_sidebar_app_id_column_and_constraint.down.sql
new file mode 100644
index 0000000000000..613e17ed20933
--- /dev/null
+++ b/coderd/database/migrations/000342_ai_task_sidebar_app_id_column_and_constraint.down.sql
@@ -0,0 +1,52 @@
+-- Drop the check constraint first
+ALTER TABLE workspace_builds DROP CONSTRAINT workspace_builds_ai_task_sidebar_app_id_required;
+
+-- Revert ai_task_sidebar_app_id back to ai_tasks_sidebar_app_id in workspace_builds table
+ALTER TABLE workspace_builds DROP CONSTRAINT workspace_builds_ai_task_sidebar_app_id_fkey;
+
+ALTER TABLE workspace_builds RENAME COLUMN ai_task_sidebar_app_id TO ai_tasks_sidebar_app_id;
+
+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);
+
+-- Revert the workspace_build_with_user view to use the original column name
+DROP VIEW workspace_build_with_user;
+
+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.';
diff --git a/coderd/database/migrations/000342_ai_task_sidebar_app_id_column_and_constraint.up.sql b/coderd/database/migrations/000342_ai_task_sidebar_app_id_column_and_constraint.up.sql
new file mode 100644
index 0000000000000..3577b9396b0df
--- /dev/null
+++ b/coderd/database/migrations/000342_ai_task_sidebar_app_id_column_and_constraint.up.sql
@@ -0,0 +1,66 @@
+-- Rename ai_tasks_sidebar_app_id to ai_task_sidebar_app_id in workspace_builds table
+ALTER TABLE workspace_builds DROP CONSTRAINT workspace_builds_ai_tasks_sidebar_app_id_fkey;
+
+ALTER TABLE workspace_builds RENAME COLUMN ai_tasks_sidebar_app_id TO ai_task_sidebar_app_id;
+
+ALTER TABLE workspace_builds ADD CONSTRAINT workspace_builds_ai_task_sidebar_app_id_fkey FOREIGN KEY (ai_task_sidebar_app_id) REFERENCES workspace_apps(id);
+
+-- if has_ai_task is true, ai_task_sidebar_app_id MUST be set
+-- ai_task_sidebar_app_id can ONLY be set if has_ai_task is true
+--
+-- has_ai_task | ai_task_sidebar_app_id | Result
+-- ------------|------------------------|---------------
+-- NULL | NULL | TRUE (passes)
+-- NULL | NOT NULL | FALSE (fails)
+-- FALSE | NULL | TRUE (passes)
+-- FALSE | NOT NULL | FALSE (fails)
+-- TRUE | NULL | FALSE (fails)
+-- TRUE | NOT NULL | TRUE (passes)
+ALTER TABLE workspace_builds
+ ADD CONSTRAINT workspace_builds_ai_task_sidebar_app_id_required CHECK (
+ ((has_ai_task IS NULL OR has_ai_task = false) AND ai_task_sidebar_app_id IS NULL)
+ OR (has_ai_task = true AND ai_task_sidebar_app_id IS NOT NULL)
+ );
+
+-- Update the workspace_build_with_user view to use the new column name
+DROP VIEW workspace_build_with_user;
+
+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_task_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.';
diff --git a/coderd/database/models.go b/coderd/database/models.go
index 0faccbb0eeb80..d964b0e2e57ad 100644
--- a/coderd/database/models.go
+++ b/coderd/database/models.go
@@ -3865,7 +3865,7 @@ type WorkspaceBuild struct {
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
- AITasksSidebarAppID uuid.NullUUID `db:"ai_tasks_sidebar_app_id" json:"ai_tasks_sidebar_app_id"`
+ AITaskSidebarAppID uuid.NullUUID `db:"ai_task_sidebar_app_id" json:"ai_task_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"`
@@ -3896,7 +3896,7 @@ type WorkspaceBuildTable struct {
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
- AITasksSidebarAppID uuid.NullUUID `db:"ai_tasks_sidebar_app_id" json:"ai_tasks_sidebar_app_id"`
+ AITaskSidebarAppID uuid.NullUUID `db:"ai_task_sidebar_app_id" json:"ai_task_sidebar_app_id"`
}
type WorkspaceLatestBuild struct {
diff --git a/coderd/database/querier.go b/coderd/database/querier.go
index 06f51785aa1af..6845f95e188b3 100644
--- a/coderd/database/querier.go
+++ b/coderd/database/querier.go
@@ -596,6 +596,7 @@ type sqlcQuerier interface {
UpdateTemplateDeletedByID(ctx context.Context, arg UpdateTemplateDeletedByIDParams) error
UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) error
UpdateTemplateScheduleByID(ctx context.Context, arg UpdateTemplateScheduleByIDParams) error
+ UpdateTemplateVersionAITaskByJobID(ctx context.Context, arg UpdateTemplateVersionAITaskByJobIDParams) error
UpdateTemplateVersionByID(ctx context.Context, arg UpdateTemplateVersionByIDParams) error
UpdateTemplateVersionDescriptionByJobID(ctx context.Context, arg UpdateTemplateVersionDescriptionByJobIDParams) error
UpdateTemplateVersionExternalAuthProvidersByJobID(ctx context.Context, arg UpdateTemplateVersionExternalAuthProvidersByJobIDParams) error
@@ -625,6 +626,7 @@ type sqlcQuerier interface {
UpdateWorkspaceAppHealthByID(ctx context.Context, arg UpdateWorkspaceAppHealthByIDParams) error
UpdateWorkspaceAutomaticUpdates(ctx context.Context, arg UpdateWorkspaceAutomaticUpdatesParams) error
UpdateWorkspaceAutostart(ctx context.Context, arg UpdateWorkspaceAutostartParams) error
+ UpdateWorkspaceBuildAITaskByID(ctx context.Context, arg UpdateWorkspaceBuildAITaskByIDParams) error
UpdateWorkspaceBuildCostByID(ctx context.Context, arg UpdateWorkspaceBuildCostByIDParams) error
UpdateWorkspaceBuildDeadlineByID(ctx context.Context, arg UpdateWorkspaceBuildDeadlineByIDParams) error
UpdateWorkspaceBuildProvisionerStateByID(ctx context.Context, arg UpdateWorkspaceBuildProvisionerStateByIDParams) error
diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go
index cc477bcccbbee..e44c35d2d22f4 100644
--- a/coderd/database/queries.sql.go
+++ b/coderd/database/queries.sql.go
@@ -11926,11 +11926,10 @@ INSERT INTO
readme,
job_id,
created_by,
- source_example_id,
- has_ai_task
+ source_example_id
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
`
type InsertTemplateVersionParams struct {
@@ -11945,7 +11944,6 @@ type InsertTemplateVersionParams struct {
JobID uuid.UUID `db:"job_id" json:"job_id"`
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
}
func (q *sqlQuerier) InsertTemplateVersion(ctx context.Context, arg InsertTemplateVersionParams) error {
@@ -11961,7 +11959,6 @@ func (q *sqlQuerier) InsertTemplateVersion(ctx context.Context, arg InsertTempla
arg.JobID,
arg.CreatedBy,
arg.SourceExampleID,
- arg.HasAITask,
)
return err
}
@@ -11987,6 +11984,27 @@ func (q *sqlQuerier) UnarchiveTemplateVersion(ctx context.Context, arg Unarchive
return err
}
+const updateTemplateVersionAITaskByJobID = `-- name: UpdateTemplateVersionAITaskByJobID :exec
+UPDATE
+ template_versions
+SET
+ has_ai_task = $2,
+ updated_at = $3
+WHERE
+ job_id = $1
+`
+
+type UpdateTemplateVersionAITaskByJobIDParams struct {
+ JobID uuid.UUID `db:"job_id" json:"job_id"`
+ HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
+ UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
+}
+
+func (q *sqlQuerier) UpdateTemplateVersionAITaskByJobID(ctx context.Context, arg UpdateTemplateVersionAITaskByJobIDParams) error {
+ _, err := q.db.ExecContext(ctx, updateTemplateVersionAITaskByJobID, arg.JobID, arg.HasAITask, arg.UpdatedAt)
+ return err
+}
+
const updateTemplateVersionByID = `-- name: UpdateTemplateVersionByID :exec
UPDATE
template_versions
@@ -14312,7 +14330,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_agents.deleted,
- 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
+ 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_task_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
@@ -14422,7 +14440,7 @@ func (q *sqlQuerier) GetWorkspaceAgentAndLatestBuildByAuthToken(ctx context.Cont
&i.WorkspaceBuild.MaxDeadline,
&i.WorkspaceBuild.TemplateVersionPresetID,
&i.WorkspaceBuild.HasAITask,
- &i.WorkspaceBuild.AITasksSidebarAppID,
+ &i.WorkspaceBuild.AITaskSidebarAppID,
&i.WorkspaceBuild.InitiatorByAvatarUrl,
&i.WorkspaceBuild.InitiatorByUsername,
&i.WorkspaceBuild.InitiatorByName,
@@ -17039,7 +17057,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.has_ai_task, wb.ai_tasks_sidebar_app_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_task_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
@@ -17095,7 +17113,7 @@ func (q *sqlQuerier) GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, t
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17195,7 +17213,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, has_ai_task, ai_tasks_sidebar_app_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_task_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17226,7 +17244,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17235,7 +17253,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.has_ai_task, wb.ai_tasks_sidebar_app_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_task_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
@@ -17275,7 +17293,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuilds(ctx context.Context) ([]WorkspaceB
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17294,7 +17312,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.has_ai_task, wb.ai_tasks_sidebar_app_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_task_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
@@ -17336,7 +17354,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context,
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17356,7 +17374,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, has_ai_task, ai_tasks_sidebar_app_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_task_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17385,7 +17403,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17395,7 +17413,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, has_ai_task, ai_tasks_sidebar_app_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_task_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17424,7 +17442,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17434,7 +17452,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, has_ai_task, ai_tasks_sidebar_app_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_task_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17467,7 +17485,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Co
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17544,7 +17562,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, has_ai_task, ai_tasks_sidebar_app_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_task_sidebar_app_id, initiator_by_avatar_url, initiator_by_username, initiator_by_name
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -17616,7 +17634,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceID(ctx context.Context, arg Ge
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17635,7 +17653,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, 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
+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_task_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) {
@@ -17664,7 +17682,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, created
&i.MaxDeadline,
&i.TemplateVersionPresetID,
&i.HasAITask,
- &i.AITasksSidebarAppID,
+ &i.AITaskSidebarAppID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
&i.InitiatorByName,
@@ -17698,11 +17716,10 @@ INSERT INTO
deadline,
max_deadline,
reason,
- template_version_preset_id,
- has_ai_task
+ template_version_preset_id
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
`
type InsertWorkspaceBuildParams struct {
@@ -17720,7 +17737,6 @@ type InsertWorkspaceBuildParams struct {
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
Reason BuildReason `db:"reason" json:"reason"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
- HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
}
func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) error {
@@ -17739,7 +17755,33 @@ func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspa
arg.MaxDeadline,
arg.Reason,
arg.TemplateVersionPresetID,
+ )
+ return err
+}
+
+const updateWorkspaceBuildAITaskByID = `-- name: UpdateWorkspaceBuildAITaskByID :exec
+UPDATE
+ workspace_builds
+SET
+ has_ai_task = $1,
+ ai_task_sidebar_app_id = $2,
+ updated_at = $3::timestamptz
+WHERE id = $4::uuid
+`
+
+type UpdateWorkspaceBuildAITaskByIDParams struct {
+ HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
+ SidebarAppID uuid.NullUUID `db:"sidebar_app_id" json:"sidebar_app_id"`
+ UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
+ ID uuid.UUID `db:"id" json:"id"`
+}
+
+func (q *sqlQuerier) UpdateWorkspaceBuildAITaskByID(ctx context.Context, arg UpdateWorkspaceBuildAITaskByIDParams) error {
+ _, err := q.db.ExecContext(ctx, updateWorkspaceBuildAITaskByID,
arg.HasAITask,
+ arg.SidebarAppID,
+ arg.UpdatedAt,
+ arg.ID,
)
return err
}
diff --git a/coderd/database/queries/templateversions.sql b/coderd/database/queries/templateversions.sql
index ac88a8b493152..4a37413d2f439 100644
--- a/coderd/database/queries/templateversions.sql
+++ b/coderd/database/queries/templateversions.sql
@@ -88,11 +88,10 @@ INSERT INTO
readme,
job_id,
created_by,
- source_example_id,
- has_ai_task
+ source_example_id
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);
-- name: UpdateTemplateVersionByID :exec
UPDATE
@@ -123,6 +122,15 @@ SET
WHERE
job_id = $1;
+-- name: UpdateTemplateVersionAITaskByJobID :exec
+UPDATE
+ template_versions
+SET
+ has_ai_task = $2,
+ updated_at = $3
+WHERE
+ job_id = $1;
+
-- name: GetPreviousTemplateVersion :one
SELECT
*
diff --git a/coderd/database/queries/workspacebuilds.sql b/coderd/database/queries/workspacebuilds.sql
index b380e5423c21c..be76b6642df1f 100644
--- a/coderd/database/queries/workspacebuilds.sql
+++ b/coderd/database/queries/workspacebuilds.sql
@@ -121,11 +121,10 @@ INSERT INTO
deadline,
max_deadline,
reason,
- template_version_preset_id,
- has_ai_task
+ template_version_preset_id
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15);
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);
-- name: UpdateWorkspaceBuildCostByID :exec
UPDATE
@@ -152,6 +151,15 @@ SET
updated_at = @updated_at::timestamptz
WHERE id = @id::uuid;
+-- name: UpdateWorkspaceBuildAITaskByID :exec
+UPDATE
+ workspace_builds
+SET
+ has_ai_task = @has_ai_task,
+ ai_task_sidebar_app_id = @sidebar_app_id,
+ updated_at = @updated_at::timestamptz
+WHERE id = @id::uuid;
+
-- name: GetActiveWorkspaceBuildsByTemplateID :many
SELECT wb.*
FROM (
diff --git a/coderd/database/sqlc.yaml b/coderd/database/sqlc.yaml
index 85bb286881f97..b96dabd1fc187 100644
--- a/coderd/database/sqlc.yaml
+++ b/coderd/database/sqlc.yaml
@@ -148,7 +148,7 @@ sql:
crypto_key_feature_oidc_convert: CryptoKeyFeatureOIDCConvert
stale_interval_ms: StaleIntervalMS
has_ai_task: HasAITask
- ai_tasks_sidebar_app_id: AITasksSidebarAppID
+ ai_task_sidebar_app_id: AITaskSidebarAppID
latest_build_has_ai_task: LatestBuildHasAITask
rules:
- name: do-not-use-public-schema-in-queries
diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go
index 4e53402fd7eed..f545169c93b31 100644
--- a/coderd/provisionerdserver/provisionerdserver.go
+++ b/coderd/provisionerdserver/provisionerdserver.go
@@ -1655,6 +1655,17 @@ func (s *server) completeTemplateImportJob(ctx context.Context, job database.Pro
if err != nil {
return xerrors.Errorf("update template version external auth providers: %w", err)
}
+ err = db.UpdateTemplateVersionAITaskByJobID(ctx, database.UpdateTemplateVersionAITaskByJobIDParams{
+ JobID: jobID,
+ HasAITask: sql.NullBool{
+ Bool: jobType.TemplateImport.HasAiTasks,
+ Valid: true,
+ },
+ UpdatedAt: now,
+ })
+ if err != nil {
+ return xerrors.Errorf("update template version external auth providers: %w", err)
+ }
// Process terraform values
plan := jobType.TemplateImport.Plan
@@ -1867,6 +1878,37 @@ func (s *server) completeWorkspaceBuildJob(ctx context.Context, job database.Pro
}
}
+ var sidebarAppID uuid.NullUUID
+ hasAITask := len(jobType.WorkspaceBuild.AiTasks) == 1
+ if hasAITask {
+ task := jobType.WorkspaceBuild.AiTasks[0]
+ if task.SidebarApp == nil {
+ return xerrors.Errorf("update ai task: sidebar app is nil")
+ }
+
+ id, err := uuid.Parse(task.SidebarApp.Id)
+ if err != nil {
+ return xerrors.Errorf("parse sidebar app id: %w", err)
+ }
+
+ sidebarAppID = uuid.NullUUID{UUID: id, Valid: true}
+ }
+
+ // Regardless of whether there is an AI task or not, update the field to indicate one way or the other since it
+ // always defaults to nil. ONLY if has_ai_task=true MUST ai_task_sidebar_app_id be set.
+ err = db.UpdateWorkspaceBuildAITaskByID(ctx, database.UpdateWorkspaceBuildAITaskByIDParams{
+ ID: workspaceBuild.ID,
+ HasAITask: sql.NullBool{
+ Bool: hasAITask,
+ Valid: true,
+ },
+ SidebarAppID: sidebarAppID,
+ UpdatedAt: now,
+ })
+ if err != nil {
+ return xerrors.Errorf("update workspace build ai tasks flag: %w", err)
+ }
+
// Insert timings inside the transaction now
// nolint:exhaustruct // The other fields are set further down.
params := database.InsertProvisionerJobTimingsParams{
diff --git a/coderd/provisionerdserver/provisionerdserver_test.go b/coderd/provisionerdserver/provisionerdserver_test.go
index dfa767b297f4c..66684835650a8 100644
--- a/coderd/provisionerdserver/provisionerdserver_test.go
+++ b/coderd/provisionerdserver/provisionerdserver_test.go
@@ -2435,6 +2435,233 @@ func TestCompleteJob(t *testing.T) {
testutil.RequireReceive(ctx, t, done)
require.Equal(t, replacements, orchestrator.replacements)
})
+
+ t.Run("AITasks", func(t *testing.T) {
+ t.Parallel()
+
+ // has_ai_task has a default value of nil, but once the template import completes it will have a value;
+ // it is set to "true" if the template has any coder_ai_task resources defined.
+ t.Run("TemplateImport", func(t *testing.T) {
+ type testcase struct {
+ name string
+ input *proto.CompletedJob_TemplateImport
+ expected bool
+ }
+
+ for _, tc := range []testcase{
+ {
+ name: "has_ai_task is false by default",
+ input: &proto.CompletedJob_TemplateImport{
+ // HasAiTasks is not set.
+ Plan: []byte("{}"),
+ },
+ expected: false,
+ },
+ {
+ name: "has_ai_task gets set to true",
+ input: &proto.CompletedJob_TemplateImport{
+ HasAiTasks: true,
+ Plan: []byte("{}"),
+ },
+ expected: true,
+ },
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+
+ srv, db, _, pd := setup(t, false, &overrides{})
+
+ importJobID := uuid.New()
+ tvID := uuid.New()
+ template := dbgen.Template(t, db, database.Template{
+ Name: "template",
+ Provisioner: database.ProvisionerTypeEcho,
+ OrganizationID: pd.OrganizationID,
+ })
+ version := dbgen.TemplateVersion(t, db, database.TemplateVersion{
+ ID: tvID,
+ OrganizationID: pd.OrganizationID,
+ TemplateID: uuid.NullUUID{
+ UUID: template.ID,
+ Valid: true,
+ },
+ JobID: importJobID,
+ })
+ _ = version
+
+ ctx := testutil.Context(t, testutil.WaitShort)
+ job, err := db.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
+ ID: importJobID,
+ CreatedAt: dbtime.Now(),
+ UpdatedAt: dbtime.Now(),
+ OrganizationID: pd.OrganizationID,
+ InitiatorID: uuid.New(),
+ Input: must(json.Marshal(provisionerdserver.TemplateVersionImportJob{
+ TemplateVersionID: tvID,
+ })),
+ Provisioner: database.ProvisionerTypeEcho,
+ StorageMethod: database.ProvisionerStorageMethodFile,
+ Type: database.ProvisionerJobTypeTemplateVersionImport,
+ Tags: pd.Tags,
+ })
+ require.NoError(t, err)
+
+ _, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{
+ OrganizationID: pd.OrganizationID,
+ WorkerID: uuid.NullUUID{
+ UUID: pd.ID,
+ Valid: true,
+ },
+ Types: []database.ProvisionerType{database.ProvisionerTypeEcho},
+ ProvisionerTags: must(json.Marshal(job.Tags)),
+ StartedAt: sql.NullTime{Time: job.CreatedAt, Valid: true},
+ })
+ require.NoError(t, err)
+
+ version, err = db.GetTemplateVersionByID(ctx, tvID)
+ require.NoError(t, err)
+ require.False(t, version.HasAITask.Valid) // Value should be nil (i.e. valid = false).
+
+ completedJob := proto.CompletedJob{
+ JobId: job.ID.String(),
+ Type: &proto.CompletedJob_TemplateImport_{
+ TemplateImport: tc.input,
+ },
+ }
+ _, err = srv.CompleteJob(ctx, &completedJob)
+ require.NoError(t, err)
+
+ version, err = db.GetTemplateVersionByID(ctx, tvID)
+ require.NoError(t, err)
+ require.True(t, version.HasAITask.Valid) // We ALWAYS expect a value to be set, therefore not nil, i.e. valid = true.
+ require.Equal(t, tc.expected, version.HasAITask.Bool)
+ })
+ }
+ })
+
+ // has_ai_task has a default value of nil, but once the workspace build completes it will have a value;
+ // it is set to "true" if the related template has any coder_ai_task resources defined, and its sidebar app ID
+ // will be set as well in that case.
+ t.Run("WorkspaceBuild", func(t *testing.T) {
+ type testcase struct {
+ name string
+ input *proto.CompletedJob_WorkspaceBuild
+ expected bool
+ }
+
+ sidebarAppID := uuid.NewString()
+ for _, tc := range []testcase{
+ {
+ name: "has_ai_task is false by default",
+ input: &proto.CompletedJob_WorkspaceBuild{
+ // No AiTasks defined.
+ },
+ expected: false,
+ },
+ {
+ name: "has_ai_task is set to true",
+ input: &proto.CompletedJob_WorkspaceBuild{
+ AiTasks: []*sdkproto.AITask{
+ {
+ Id: uuid.NewString(),
+ SidebarApp: &sdkproto.AITaskSidebarApp{
+ Id: sidebarAppID,
+ },
+ },
+ },
+ },
+ expected: true,
+ },
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+
+ srv, db, _, pd := setup(t, false, &overrides{})
+
+ importJobID := uuid.New()
+ tvID := uuid.New()
+ template := dbgen.Template(t, db, database.Template{
+ Name: "template",
+ Provisioner: database.ProvisionerTypeEcho,
+ OrganizationID: pd.OrganizationID,
+ })
+ version := dbgen.TemplateVersion(t, db, database.TemplateVersion{
+ ID: tvID,
+ OrganizationID: pd.OrganizationID,
+ TemplateID: uuid.NullUUID{
+ UUID: template.ID,
+ Valid: true,
+ },
+ JobID: importJobID,
+ })
+ user := dbgen.User(t, db, database.User{})
+ workspaceTable := dbgen.Workspace(t, db, database.WorkspaceTable{
+ TemplateID: template.ID,
+ OwnerID: user.ID,
+ OrganizationID: pd.OrganizationID,
+ })
+ build := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
+ WorkspaceID: workspaceTable.ID,
+ TemplateVersionID: version.ID,
+ InitiatorID: user.ID,
+ Transition: database.WorkspaceTransitionStart,
+ })
+
+ ctx := testutil.Context(t, testutil.WaitShort)
+ job, err := db.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
+ ID: importJobID,
+ CreatedAt: dbtime.Now(),
+ UpdatedAt: dbtime.Now(),
+ OrganizationID: pd.OrganizationID,
+ InitiatorID: uuid.New(),
+ Input: must(json.Marshal(provisionerdserver.WorkspaceProvisionJob{
+ WorkspaceBuildID: build.ID,
+ LogLevel: "DEBUG",
+ })),
+ Provisioner: database.ProvisionerTypeEcho,
+ StorageMethod: database.ProvisionerStorageMethodFile,
+ Type: database.ProvisionerJobTypeWorkspaceBuild,
+ Tags: pd.Tags,
+ })
+ require.NoError(t, err)
+
+ _, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{
+ OrganizationID: pd.OrganizationID,
+ WorkerID: uuid.NullUUID{
+ UUID: pd.ID,
+ Valid: true,
+ },
+ Types: []database.ProvisionerType{database.ProvisionerTypeEcho},
+ ProvisionerTags: must(json.Marshal(job.Tags)),
+ StartedAt: sql.NullTime{Time: job.CreatedAt, Valid: true},
+ })
+ require.NoError(t, err)
+
+ build, err = db.GetWorkspaceBuildByID(ctx, build.ID)
+ require.NoError(t, err)
+ require.False(t, build.HasAITask.Valid) // Value should be nil (i.e. valid = false).
+
+ completedJob := proto.CompletedJob{
+ JobId: job.ID.String(),
+ Type: &proto.CompletedJob_WorkspaceBuild_{
+ WorkspaceBuild: tc.input,
+ },
+ }
+ _, err = srv.CompleteJob(ctx, &completedJob)
+ require.NoError(t, err)
+
+ build, err = db.GetWorkspaceBuildByID(ctx, build.ID)
+ require.NoError(t, err)
+ require.True(t, build.HasAITask.Valid) // We ALWAYS expect a value to be set, therefore not nil, i.e. valid = true.
+ require.Equal(t, tc.expected, build.HasAITask.Bool)
+
+ if tc.expected {
+ require.Equal(t, sidebarAppID, build.AITaskSidebarAppID.UUID.String())
+ }
+ })
+ }
+ })
+ })
}
type mockPrebuildsOrchestrator struct {
diff --git a/coderd/templateversions.go b/coderd/templateversions.go
index d9f9c3db42dd6..d79f86f1f6626 100644
--- a/coderd/templateversions.go
+++ b/coderd/templateversions.go
@@ -1730,12 +1730,6 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
String: req.ExampleID,
Valid: req.ExampleID != "",
},
- // appease the exhaustruct linter
- // TODO: set this to whether the template version defines a `coder_ai_task` tf resource
- HasAITask: sql.NullBool{
- Bool: false,
- Valid: false,
- },
})
if err != nil {
if database.IsUniqueViolation(err, database.UniqueTemplateVersionsTemplateIDNameKey) {
diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go
index 850e9dd457dd8..76e271ff3aee6 100644
--- a/coderd/workspacebuilds.go
+++ b/coderd/workspacebuilds.go
@@ -1108,8 +1108,8 @@ func (api *API) convertWorkspaceBuild(
hasAITask = &build.HasAITask.Bool
}
var aiTasksSidebarAppID *uuid.UUID
- if build.AITasksSidebarAppID.Valid {
- aiTasksSidebarAppID = &build.AITasksSidebarAppID.UUID
+ if build.AITaskSidebarAppID.Valid {
+ aiTasksSidebarAppID = &build.AITaskSidebarAppID.UUID
}
apiJob := convertProvisionerJob(job)
diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go
index 74554962fbd1e..d51a228a3f7a1 100644
--- a/coderd/workspaces_test.go
+++ b/coderd/workspaces_test.go
@@ -4509,7 +4509,10 @@ func TestWorkspaceFilterHasAITask(t *testing.T) {
// Helper function to create workspace with AI task configuration
createWorkspaceWithAIConfig := func(hasAITask sql.NullBool, jobCompleted bool, aiTaskPrompt *string) database.WorkspaceTable {
- // When a provisioner job uses these tags, no provisioner will match it
+ // When a provisioner job uses these tags, no provisioner will match it.
+ // We do this so jobs will always be stuck in "pending", allowing us to exercise the intermediary state when
+ // has_ai_task is nil and we compensate by looking at pending provisioning jobs.
+ // See GetWorkspaces clauses.
unpickableTags := database.StringMap{"custom": "true"}
ws := dbgen.Workspace(t, db, database.WorkspaceTable{
@@ -4528,20 +4531,30 @@ func TestWorkspaceFilterHasAITask(t *testing.T) {
}
job := dbgen.ProvisionerJob(t, db, pubsub, jobConfig)
+ res := dbgen.WorkspaceResource(t, db, database.WorkspaceResource{JobID: job.ID})
+ agnt := dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{ResourceID: res.ID})
+
+ var sidebarAppID uuid.UUID
+ if hasAITask.Bool {
+ sidebarApp := dbgen.WorkspaceApp(t, db, database.WorkspaceApp{AgentID: agnt.ID})
+ sidebarAppID = sidebarApp.ID
+ }
+
build := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
- WorkspaceID: ws.ID,
- TemplateVersionID: version.ID,
- InitiatorID: user.UserID,
- JobID: job.ID,
- BuildNumber: 1,
- HasAITask: hasAITask,
+ WorkspaceID: ws.ID,
+ TemplateVersionID: version.ID,
+ InitiatorID: user.UserID,
+ JobID: job.ID,
+ BuildNumber: 1,
+ HasAITask: hasAITask,
+ AITaskSidebarAppID: uuid.NullUUID{UUID: sidebarAppID, Valid: sidebarAppID != uuid.Nil},
})
if aiTaskPrompt != nil {
//nolint:gocritic // unit test
err := db.InsertWorkspaceBuildParameters(dbauthz.AsSystemRestricted(ctx), database.InsertWorkspaceBuildParametersParams{
WorkspaceBuildID: build.ID,
- Name: []string{"AI Prompt"},
+ Name: []string{provider.TaskPromptParameterName},
Value: []string{*aiTaskPrompt},
})
require.NoError(t, err)
@@ -4551,7 +4564,7 @@ func TestWorkspaceFilterHasAITask(t *testing.T) {
}
// Create test workspaces with different AI task configurations
- wsWithAITask := createWorkspaceWithAIConfig(sql.NullBool{Bool: true, Valid: true}, false, nil)
+ wsWithAITask := createWorkspaceWithAIConfig(sql.NullBool{Bool: true, Valid: true}, true, nil)
wsWithoutAITask := createWorkspaceWithAIConfig(sql.NullBool{Bool: false, Valid: true}, false, nil)
aiTaskPrompt := "Build me a web app"
@@ -4699,3 +4712,51 @@ func TestWorkspaceAppUpsertRestart(t *testing.T) {
require.Equal(t, codersdk.ProvisionerJobSucceeded, workspace.LatestBuild.Job.Status)
require.Empty(t, workspace.LatestBuild.Job.Error)
}
+
+func TestMultipleAITasksDisallowed(t *testing.T) {
+ t.Parallel()
+
+ db, pubsub := dbtestutil.NewDB(t)
+ client := coderdtest.New(t, &coderdtest.Options{
+ Database: db,
+ Pubsub: pubsub,
+ IncludeProvisionerDaemon: true,
+ })
+ user := coderdtest.CreateFirstUser(t, client)
+
+ version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
+ Parse: echo.ParseComplete,
+ ProvisionPlan: []*proto.Response{{
+ Type: &proto.Response_Plan{
+ Plan: &proto.PlanComplete{
+ HasAiTasks: true,
+ AiTasks: []*proto.AITask{
+ {
+ Id: uuid.NewString(),
+ SidebarApp: &proto.AITaskSidebarApp{
+ Id: uuid.NewString(),
+ },
+ },
+ {
+ Id: uuid.NewString(),
+ SidebarApp: &proto.AITaskSidebarApp{
+ Id: uuid.NewString(),
+ },
+ },
+ },
+ },
+ },
+ }},
+ })
+ coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
+ template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
+
+ ws := coderdtest.CreateWorkspace(t, client, template.ID)
+ coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID)
+
+ //nolint: gocritic // testing
+ ctx := dbauthz.AsSystemRestricted(t.Context())
+ pj, err := db.GetProvisionerJobByID(ctx, ws.LatestBuild.Job.ID)
+ require.NoError(t, err)
+ require.Contains(t, pj.Error.String, "only one 'coder_ai_task' resource can be provisioned per template")
+}
diff --git a/coderd/wsbuilder/wsbuilder.go b/coderd/wsbuilder/wsbuilder.go
index f327e071c3946..0b11240e19db0 100644
--- a/coderd/wsbuilder/wsbuilder.go
+++ b/coderd/wsbuilder/wsbuilder.go
@@ -426,12 +426,6 @@ func (b *Builder) buildTx(authFunc func(action policy.Action, object rbac.Object
UUID: b.templateVersionPresetID,
Valid: b.templateVersionPresetID != uuid.Nil,
},
- // appease the exhaustruct linter
- // TODO: set this to whether the build included a `coder_ai_task` tf resource
- HasAITask: sql.NullBool{
- Bool: false,
- Valid: false,
- },
})
if err != nil {
code := http.StatusInternalServerError
diff --git a/docs/admin/security/audit-logs.md b/docs/admin/security/audit-logs.md
index 7b0b852419f21..01b3d8e61d595 100644
--- a/docs/admin/security/audit-logs.md
+++ b/docs/admin/security/audit-logs.md
@@ -31,7 +31,7 @@ We track the following resources:
| 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 |
deleted | 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 |
| 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 |
|
+| WorkspaceBuild
start, stop | Field | Tracked |
| ai_task_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 bd4987bae24e2..120b4ed684bdf 100644
--- a/enterprise/audit/table.go
+++ b/enterprise/audit/table.go
@@ -195,7 +195,7 @@ var auditableResourcesTypes = map[any]map[string]Action{
"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.
+ "ai_task_sidebar_app_id": ActionIgnore, // Never changes.
},
&database.AuditableGroup{}: {
"id": ActionTrack,
diff --git a/provisioner/terraform/executor.go b/provisioner/terraform/executor.go
index b29c21eff000c..ea63f8c59877e 100644
--- a/provisioner/terraform/executor.go
+++ b/provisioner/terraform/executor.go
@@ -361,6 +361,8 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
Plan: planJSON,
ResourceReplacements: resReps,
ModuleFiles: moduleFiles,
+ HasAiTasks: state.HasAITasks,
+ AiTasks: state.AITasks,
}
return msg, nil
@@ -577,6 +579,7 @@ func (e *executor) apply(
ExternalAuthProviders: state.ExternalAuthProviders,
State: stateContent,
Timings: e.timings.aggregate(),
+ AiTasks: state.AITasks,
}, nil
}
diff --git a/provisioner/terraform/provision_test.go b/provisioner/terraform/provision_test.go
index dc4545d137e89..d067965997308 100644
--- a/provisioner/terraform/provision_test.go
+++ b/provisioner/terraform/provision_test.go
@@ -23,6 +23,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/coder/terraform-provider-coder/v2/provider"
+
"cdr.dev/slog"
"cdr.dev/slog/sloggers/slogtest"
@@ -1046,6 +1048,93 @@ func TestProvision(t *testing.T) {
}},
},
},
+ {
+ Name: "ai-task-required-prompt-param",
+ Files: map[string]string{
+ "main.tf": `terraform {
+ required_providers {
+ coder = {
+ source = "coder/coder"
+ version = ">= 2.7.0"
+ }
+ }
+ }
+ resource "coder_ai_task" "a" {
+ sidebar_app {
+ id = "7128be08-8722-44cb-bbe1-b5a391c4d94b" # fake ID, irrelevant here anyway but needed for validation
+ }
+ }
+ `,
+ },
+ Request: &proto.PlanRequest{},
+ Response: &proto.PlanComplete{
+ Error: fmt.Sprintf("plan resources: coder_parameter named '%s' is required when 'coder_ai_task' resource is defined", provider.TaskPromptParameterName),
+ },
+ },
+ {
+ Name: "ai-task-multiple-allowed-in-plan",
+ Files: map[string]string{
+ "main.tf": fmt.Sprintf(`terraform {
+ required_providers {
+ coder = {
+ source = "coder/coder"
+ version = ">= 2.7.0"
+ }
+ }
+ }
+ data "coder_parameter" "prompt" {
+ name = "%s"
+ type = "string"
+ }
+ resource "coder_ai_task" "a" {
+ sidebar_app {
+ id = "7128be08-8722-44cb-bbe1-b5a391c4d94b" # fake ID, irrelevant here anyway but needed for validation
+ }
+ }
+ resource "coder_ai_task" "b" {
+ sidebar_app {
+ id = "7128be08-8722-44cb-bbe1-b5a391c4d94b" # fake ID, irrelevant here anyway but needed for validation
+ }
+ }
+ `, provider.TaskPromptParameterName),
+ },
+ Request: &proto.PlanRequest{},
+ Response: &proto.PlanComplete{
+ Resources: []*proto.Resource{
+ {
+ Name: "a",
+ Type: "coder_ai_task",
+ },
+ {
+ Name: "b",
+ Type: "coder_ai_task",
+ },
+ },
+ Parameters: []*proto.RichParameter{
+ {
+ Name: provider.TaskPromptParameterName,
+ Type: "string",
+ Required: true,
+ FormType: proto.ParameterFormType_INPUT,
+ },
+ },
+ AiTasks: []*proto.AITask{
+ {
+ Id: "a",
+ SidebarApp: &proto.AITaskSidebarApp{
+ Id: "7128be08-8722-44cb-bbe1-b5a391c4d94b",
+ },
+ },
+ {
+ Id: "b",
+ SidebarApp: &proto.AITaskSidebarApp{
+ Id: "7128be08-8722-44cb-bbe1-b5a391c4d94b",
+ },
+ },
+ },
+ HasAiTasks: true,
+ },
+ },
}
// Remove unused cache dirs before running tests.
@@ -1146,6 +1235,8 @@ func TestProvision(t *testing.T) {
modulesWant, err := json.Marshal(testCase.Response.Modules)
require.NoError(t, err)
require.Equal(t, string(modulesWant), string(modulesGot))
+
+ require.Equal(t, planComplete.HasAiTasks, testCase.Response.HasAiTasks)
}
if testCase.Apply {
diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go
index d28daf633d672..53dcc94831ab0 100644
--- a/provisioner/terraform/resources.go
+++ b/provisioner/terraform/resources.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"math"
+ "slices"
"strings"
"github.com/awalterschulze/gographviz"
@@ -162,10 +163,29 @@ type State struct {
Parameters []*proto.RichParameter
Presets []*proto.Preset
ExternalAuthProviders []*proto.ExternalAuthProviderResource
+ AITasks []*proto.AITask
+ HasAITasks bool
}
var ErrInvalidTerraformAddr = xerrors.New("invalid terraform address")
+// hasAITaskResources is used to determine if a template has *any* `coder_ai_task` resources defined. During template
+// import, it's possible that none of these have `count=1` since count may be dependent on the value of a `coder_parameter`
+// or something else.
+// We need to know at template import if these resources exist to inform the frontend of their existence.
+func hasAITaskResources(graph *gographviz.Graph) bool {
+ for _, node := range graph.Nodes.Lookup {
+ // Check if this node is a coder_ai_task resource
+ if label, exists := node.Attrs["label"]; exists {
+ labelValue := strings.Trim(label, `"`)
+ if strings.HasPrefix(labelValue, "coder_ai_task.") {
+ return true
+ }
+ }
+ }
+ return false
+}
+
// ConvertState consumes Terraform state and a GraphViz representation
// produced by `terraform graph` to produce resources consumable by Coder.
// nolint:gocognit // This function makes more sense being large for now, until refactored.
@@ -189,6 +209,7 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s
// Extra array to preserve the order of rich parameters.
tfResourcesRichParameters := make([]*tfjson.StateResource, 0)
tfResourcesPresets := make([]*tfjson.StateResource, 0)
+ tfResourcesAITasks := make([]*tfjson.StateResource, 0)
var findTerraformResources func(mod *tfjson.StateModule)
findTerraformResources = func(mod *tfjson.StateModule) {
for _, module := range mod.ChildModules {
@@ -201,6 +222,9 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s
if resource.Type == "coder_workspace_preset" {
tfResourcesPresets = append(tfResourcesPresets, resource)
}
+ if resource.Type == "coder_ai_task" {
+ tfResourcesAITasks = append(tfResourcesAITasks, resource)
+ }
label := convertAddressToLabel(resource.Address)
if tfResourcesByLabel[label] == nil {
@@ -969,6 +993,27 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s
return nil, xerrors.Errorf("a maximum of 1 coder_workspace_preset can be marked as default, but %d are set", defaultPresets)
}
+ // This will only pick up resources which will actually be created.
+ aiTasks := make([]*proto.AITask, 0, len(tfResourcesAITasks))
+ for _, resource := range tfResourcesAITasks {
+ var task provider.AITask
+ err = mapstructure.Decode(resource.AttributeValues, &task)
+ if err != nil {
+ return nil, xerrors.Errorf("decode coder_ai_task attributes: %w", err)
+ }
+
+ if len(task.SidebarApp) < 1 {
+ return nil, xerrors.Errorf("coder_ai_task has no sidebar_app defined")
+ }
+
+ aiTasks = append(aiTasks, &proto.AITask{
+ Id: task.ID,
+ SidebarApp: &proto.AITaskSidebarApp{
+ Id: task.SidebarApp[0].ID,
+ },
+ })
+ }
+
// A map is used to ensure we don't have duplicates!
externalAuthProvidersMap := map[string]*proto.ExternalAuthProviderResource{}
for _, tfResources := range tfResourcesByLabel {
@@ -999,11 +1044,23 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s
externalAuthProviders = append(externalAuthProviders, it)
}
+ hasAITasks := hasAITaskResources(graph)
+ if hasAITasks {
+ hasPromptParam := slices.ContainsFunc(parameters, func(param *proto.RichParameter) bool {
+ return param.Name == provider.TaskPromptParameterName
+ })
+ if !hasPromptParam {
+ return nil, xerrors.Errorf("coder_parameter named '%s' is required when 'coder_ai_task' resource is defined", provider.TaskPromptParameterName)
+ }
+ }
+
return &State{
Resources: resources,
Parameters: parameters,
Presets: presets,
ExternalAuthProviders: externalAuthProviders,
+ HasAITasks: hasAITasks,
+ AITasks: aiTasks,
}, nil
}
diff --git a/provisioner/terraform/resources_test.go b/provisioner/terraform/resources_test.go
index dd301e638ef6e..1575c6c9c159e 100644
--- a/provisioner/terraform/resources_test.go
+++ b/provisioner/terraform/resources_test.go
@@ -16,6 +16,8 @@ import (
"github.com/stretchr/testify/require"
protobuf "google.golang.org/protobuf/proto"
+ "github.com/coder/terraform-provider-coder/v2/provider"
+
"cdr.dev/slog"
"cdr.dev/slog/sloggers/slogtest"
@@ -1522,6 +1524,55 @@ func TestInstanceIDAssociation(t *testing.T) {
}
}
+func TestAITasks(t *testing.T) {
+ t.Parallel()
+ ctx, logger := ctxAndLogger(t)
+
+ t.Run("Prompt parameter is required", func(t *testing.T) {
+ t.Parallel()
+
+ // nolint:dogsled
+ _, filename, _, _ := runtime.Caller(0)
+
+ dir := filepath.Join(filepath.Dir(filename), "testdata", "resources", "ai-tasks-missing-prompt")
+ tfPlanRaw, err := os.ReadFile(filepath.Join(dir, "ai-tasks-missing-prompt.tfplan.json"))
+ require.NoError(t, err)
+ var tfPlan tfjson.Plan
+ err = json.Unmarshal(tfPlanRaw, &tfPlan)
+ require.NoError(t, err)
+ tfPlanGraph, err := os.ReadFile(filepath.Join(dir, "ai-tasks-missing-prompt.tfplan.dot"))
+ require.NoError(t, err)
+
+ state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PlannedValues.RootModule, tfPlan.PriorState.Values.RootModule}, string(tfPlanGraph), logger)
+ require.Nil(t, state)
+ require.ErrorContains(t, err, fmt.Sprintf("coder_parameter named '%s' is required when 'coder_ai_task' resource is defined", provider.TaskPromptParameterName))
+ })
+
+ t.Run("Multiple tasks can be defined", func(t *testing.T) {
+ t.Parallel()
+
+ // nolint:dogsled
+ _, filename, _, _ := runtime.Caller(0)
+
+ dir := filepath.Join(filepath.Dir(filename), "testdata", "resources", "ai-tasks-multiple")
+ tfPlanRaw, err := os.ReadFile(filepath.Join(dir, "ai-tasks-multiple.tfplan.json"))
+ require.NoError(t, err)
+ var tfPlan tfjson.Plan
+ err = json.Unmarshal(tfPlanRaw, &tfPlan)
+ require.NoError(t, err)
+ tfPlanGraph, err := os.ReadFile(filepath.Join(dir, "ai-tasks-multiple.tfplan.dot"))
+ require.NoError(t, err)
+
+ state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PlannedValues.RootModule, tfPlan.PriorState.Values.RootModule}, string(tfPlanGraph), logger)
+ require.NotNil(t, state)
+ require.NoError(t, err)
+ require.True(t, state.HasAITasks)
+ // Multiple coder_ai_tasks resources can be defined, but only 1 is allowed.
+ // This is validated once all parameters are resolved etc as part of the workspace build, but for now we can allow it.
+ require.Len(t, state.AITasks, 2)
+ })
+}
+
// sortResource ensures resources appear in a consistent ordering
// to prevent tests from flaking.
func sortResources(resources []*proto.Resource) {
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfplan.dot b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfplan.dot
new file mode 100644
index 0000000000000..758e6c990ec1e
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfplan.dot
@@ -0,0 +1,22 @@
+digraph {
+ compound = "true"
+ newrank = "true"
+ subgraph "root" {
+ "[root] coder_agent.main (expand)" [label = "coder_agent.main", shape = "box"]
+ "[root] coder_ai_task.a (expand)" [label = "coder_ai_task.a", shape = "box"]
+ "[root] data.coder_provisioner.me (expand)" [label = "data.coder_provisioner.me", shape = "box"]
+ "[root] data.coder_workspace.me (expand)" [label = "data.coder_workspace.me", shape = "box"]
+ "[root] data.coder_workspace_owner.me (expand)" [label = "data.coder_workspace_owner.me", shape = "box"]
+ "[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
+ "[root] coder_agent.main (expand)" -> "[root] data.coder_provisioner.me (expand)"
+ "[root] coder_ai_task.a (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_provisioner.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_workspace.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_workspace_owner.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_agent.main (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_ai_task.a (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_workspace.me (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_workspace_owner.me (expand)"
+ "[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
+ }
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfplan.json b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfplan.json
new file mode 100644
index 0000000000000..ad255c7db7624
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfplan.json
@@ -0,0 +1,307 @@
+{
+ "format_version": "1.2",
+ "terraform_version": "1.12.2",
+ "planned_values": {
+ "root_module": {
+ "resources": [
+ {
+ "address": "coder_agent.main",
+ "mode": "managed",
+ "type": "coder_agent",
+ "name": "main",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "api_key_scope": "all",
+ "arch": "amd64",
+ "auth": "token",
+ "connection_timeout": 120,
+ "dir": null,
+ "env": null,
+ "metadata": [],
+ "motd_file": null,
+ "order": null,
+ "os": "linux",
+ "resources_monitoring": [],
+ "shutdown_script": null,
+ "startup_script": null,
+ "startup_script_behavior": "non-blocking",
+ "troubleshooting_url": null
+ },
+ "sensitive_values": {
+ "display_apps": [],
+ "metadata": [],
+ "resources_monitoring": [],
+ "token": true
+ }
+ },
+ {
+ "address": "coder_ai_task.a",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "a",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "sensitive_values": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "resource_changes": [
+ {
+ "address": "coder_agent.main",
+ "mode": "managed",
+ "type": "coder_agent",
+ "name": "main",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "change": {
+ "actions": [
+ "create"
+ ],
+ "before": null,
+ "after": {
+ "api_key_scope": "all",
+ "arch": "amd64",
+ "auth": "token",
+ "connection_timeout": 120,
+ "dir": null,
+ "env": null,
+ "metadata": [],
+ "motd_file": null,
+ "order": null,
+ "os": "linux",
+ "resources_monitoring": [],
+ "shutdown_script": null,
+ "startup_script": null,
+ "startup_script_behavior": "non-blocking",
+ "troubleshooting_url": null
+ },
+ "after_unknown": {
+ "display_apps": true,
+ "id": true,
+ "init_script": true,
+ "metadata": [],
+ "resources_monitoring": [],
+ "token": true
+ },
+ "before_sensitive": false,
+ "after_sensitive": {
+ "display_apps": [],
+ "metadata": [],
+ "resources_monitoring": [],
+ "token": true
+ }
+ }
+ },
+ {
+ "address": "coder_ai_task.a",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "a",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "change": {
+ "actions": [
+ "create"
+ ],
+ "before": null,
+ "after": {
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "after_unknown": {
+ "id": true,
+ "sidebar_app": [
+ {}
+ ]
+ },
+ "before_sensitive": false,
+ "after_sensitive": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ }
+ }
+ ],
+ "prior_state": {
+ "format_version": "1.0",
+ "terraform_version": "1.12.2",
+ "values": {
+ "root_module": {
+ "resources": [
+ {
+ "address": "data.coder_provisioner.me",
+ "mode": "data",
+ "type": "coder_provisioner",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "arch": "amd64",
+ "id": "5a6ecb8b-fd26-4cfc-91b1-651d06bee98c",
+ "os": "linux"
+ },
+ "sensitive_values": {}
+ },
+ {
+ "address": "data.coder_workspace.me",
+ "mode": "data",
+ "type": "coder_workspace",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "access_port": 443,
+ "access_url": "https://dev.coder.com/",
+ "id": "bf9ee323-4f3a-4d45-9841-2dcd6265e830",
+ "is_prebuild": false,
+ "is_prebuild_claim": false,
+ "name": "sebenza-nonix",
+ "prebuild_count": 0,
+ "start_count": 1,
+ "template_id": "",
+ "template_name": "",
+ "template_version": "",
+ "transition": "start"
+ },
+ "sensitive_values": {}
+ },
+ {
+ "address": "data.coder_workspace_owner.me",
+ "mode": "data",
+ "type": "coder_workspace_owner",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 0,
+ "values": {
+ "email": "default@example.com",
+ "full_name": "default",
+ "groups": [],
+ "id": "0b8cbfb8-3925-41fe-9f21-21b76d21edc7",
+ "login_type": null,
+ "name": "default",
+ "oidc_access_token": "",
+ "rbac_roles": [],
+ "session_token": "",
+ "ssh_private_key": "",
+ "ssh_public_key": ""
+ },
+ "sensitive_values": {
+ "groups": [],
+ "rbac_roles": [],
+ "ssh_private_key": true
+ }
+ }
+ ]
+ }
+ }
+ },
+ "configuration": {
+ "provider_config": {
+ "coder": {
+ "name": "coder",
+ "full_name": "registry.terraform.io/coder/coder",
+ "version_constraint": ">= 2.0.0"
+ }
+ },
+ "root_module": {
+ "resources": [
+ {
+ "address": "coder_agent.main",
+ "mode": "managed",
+ "type": "coder_agent",
+ "name": "main",
+ "provider_config_key": "coder",
+ "expressions": {
+ "arch": {
+ "references": [
+ "data.coder_provisioner.me.arch",
+ "data.coder_provisioner.me"
+ ]
+ },
+ "os": {
+ "references": [
+ "data.coder_provisioner.me.os",
+ "data.coder_provisioner.me"
+ ]
+ }
+ },
+ "schema_version": 1
+ },
+ {
+ "address": "coder_ai_task.a",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "a",
+ "provider_config_key": "coder",
+ "expressions": {
+ "sidebar_app": [
+ {
+ "id": {
+ "constant_value": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ }
+ ]
+ },
+ "schema_version": 1
+ },
+ {
+ "address": "data.coder_provisioner.me",
+ "mode": "data",
+ "type": "coder_provisioner",
+ "name": "me",
+ "provider_config_key": "coder",
+ "schema_version": 1
+ },
+ {
+ "address": "data.coder_workspace.me",
+ "mode": "data",
+ "type": "coder_workspace",
+ "name": "me",
+ "provider_config_key": "coder",
+ "schema_version": 1
+ },
+ {
+ "address": "data.coder_workspace_owner.me",
+ "mode": "data",
+ "type": "coder_workspace_owner",
+ "name": "me",
+ "provider_config_key": "coder",
+ "schema_version": 0
+ }
+ ]
+ }
+ },
+ "relevant_attributes": [
+ {
+ "resource": "data.coder_provisioner.me",
+ "attribute": [
+ "arch"
+ ]
+ },
+ {
+ "resource": "data.coder_provisioner.me",
+ "attribute": [
+ "os"
+ ]
+ }
+ ],
+ "timestamp": "2025-06-19T14:30:00Z",
+ "applyable": true,
+ "complete": true,
+ "errored": false
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfstate.dot b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfstate.dot
new file mode 100644
index 0000000000000..758e6c990ec1e
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfstate.dot
@@ -0,0 +1,22 @@
+digraph {
+ compound = "true"
+ newrank = "true"
+ subgraph "root" {
+ "[root] coder_agent.main (expand)" [label = "coder_agent.main", shape = "box"]
+ "[root] coder_ai_task.a (expand)" [label = "coder_ai_task.a", shape = "box"]
+ "[root] data.coder_provisioner.me (expand)" [label = "data.coder_provisioner.me", shape = "box"]
+ "[root] data.coder_workspace.me (expand)" [label = "data.coder_workspace.me", shape = "box"]
+ "[root] data.coder_workspace_owner.me (expand)" [label = "data.coder_workspace_owner.me", shape = "box"]
+ "[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
+ "[root] coder_agent.main (expand)" -> "[root] data.coder_provisioner.me (expand)"
+ "[root] coder_ai_task.a (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_provisioner.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_workspace.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_workspace_owner.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_agent.main (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_ai_task.a (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_workspace.me (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_workspace_owner.me (expand)"
+ "[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
+ }
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfstate.json b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfstate.json
new file mode 100644
index 0000000000000..4d3affb7a31ed
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/ai-tasks-missing-prompt.tfstate.json
@@ -0,0 +1,142 @@
+{
+ "format_version": "1.0",
+ "terraform_version": "1.12.2",
+ "values": {
+ "root_module": {
+ "resources": [
+ {
+ "address": "data.coder_provisioner.me",
+ "mode": "data",
+ "type": "coder_provisioner",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "arch": "amd64",
+ "id": "e838328b-8dc2-49d0-b16c-42d6375cfb34",
+ "os": "linux"
+ },
+ "sensitive_values": {}
+ },
+ {
+ "address": "data.coder_workspace.me",
+ "mode": "data",
+ "type": "coder_workspace",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "access_port": 443,
+ "access_url": "https://dev.coder.com/",
+ "id": "6a64b978-bd81-424a-92e5-d4004296f420",
+ "is_prebuild": false,
+ "is_prebuild_claim": false,
+ "name": "sebenza-nonix",
+ "prebuild_count": 0,
+ "start_count": 1,
+ "template_id": "",
+ "template_name": "",
+ "template_version": "",
+ "transition": "start"
+ },
+ "sensitive_values": {}
+ },
+ {
+ "address": "data.coder_workspace_owner.me",
+ "mode": "data",
+ "type": "coder_workspace_owner",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 0,
+ "values": {
+ "email": "default@example.com",
+ "full_name": "default",
+ "groups": [],
+ "id": "ffb2e99a-efa7-4fb9-bb2c-aa282bb636c9",
+ "login_type": null,
+ "name": "default",
+ "oidc_access_token": "",
+ "rbac_roles": [],
+ "session_token": "",
+ "ssh_private_key": "",
+ "ssh_public_key": ""
+ },
+ "sensitive_values": {
+ "groups": [],
+ "rbac_roles": [],
+ "ssh_private_key": true
+ }
+ },
+ {
+ "address": "coder_agent.main",
+ "mode": "managed",
+ "type": "coder_agent",
+ "name": "main",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "api_key_scope": "all",
+ "arch": "amd64",
+ "auth": "token",
+ "connection_timeout": 120,
+ "dir": null,
+ "display_apps": [
+ {
+ "port_forwarding_helper": true,
+ "ssh_helper": true,
+ "vscode": true,
+ "vscode_insiders": false,
+ "web_terminal": true
+ }
+ ],
+ "env": null,
+ "id": "0c95434c-9e4b-40aa-bd9b-2a0cc86f11af",
+ "init_script": "",
+ "metadata": [],
+ "motd_file": null,
+ "order": null,
+ "os": "linux",
+ "resources_monitoring": [],
+ "shutdown_script": null,
+ "startup_script": null,
+ "startup_script_behavior": "non-blocking",
+ "token": "ac32e23e-336a-4e63-a7a4-71ab85f16831",
+ "troubleshooting_url": null
+ },
+ "sensitive_values": {
+ "display_apps": [
+ {}
+ ],
+ "metadata": [],
+ "resources_monitoring": [],
+ "token": true
+ },
+ "depends_on": [
+ "data.coder_provisioner.me"
+ ]
+ },
+ {
+ "address": "coder_ai_task.a",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "a",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "id": "b83734ee-765f-45db-a37b-a1e89414be5f",
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "sensitive_values": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/main.tf b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/main.tf
new file mode 100644
index 0000000000000..236baa1c9535b
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-missing-prompt/main.tf
@@ -0,0 +1,23 @@
+terraform {
+ required_providers {
+ coder = {
+ source = "coder/coder"
+ version = ">= 2.0.0"
+ }
+ }
+}
+
+data "coder_provisioner" "me" {}
+data "coder_workspace" "me" {}
+data "coder_workspace_owner" "me" {}
+
+resource "coder_agent" "main" {
+ arch = data.coder_provisioner.me.arch
+ os = data.coder_provisioner.me.os
+}
+
+resource "coder_ai_task" "a" {
+ sidebar_app {
+ id = "5ece4674-dd35-4f16-88c8-82e40e72e2fd" # fake ID to satisfy requirement, irrelevant otherwise
+ }
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfplan.dot b/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfplan.dot
new file mode 100644
index 0000000000000..4e660599e7a9b
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfplan.dot
@@ -0,0 +1,26 @@
+digraph {
+ compound = "true"
+ newrank = "true"
+ subgraph "root" {
+ "[root] coder_ai_task.a (expand)" [label = "coder_ai_task.a", shape = "box"]
+ "[root] coder_ai_task.b (expand)" [label = "coder_ai_task.b", shape = "box"]
+ "[root] data.coder_parameter.prompt (expand)" [label = "data.coder_parameter.prompt", shape = "box"]
+ "[root] data.coder_provisioner.me (expand)" [label = "data.coder_provisioner.me", shape = "box"]
+ "[root] data.coder_workspace.me (expand)" [label = "data.coder_workspace.me", shape = "box"]
+ "[root] data.coder_workspace_owner.me (expand)" [label = "data.coder_workspace_owner.me", shape = "box"]
+ "[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
+ "[root] coder_ai_task.a (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] coder_ai_task.b (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_parameter.prompt (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_provisioner.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_workspace.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_workspace_owner.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_ai_task.a (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_ai_task.b (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_parameter.prompt (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_provisioner.me (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_workspace.me (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_workspace_owner.me (expand)"
+ "[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
+ }
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfplan.json b/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfplan.json
new file mode 100644
index 0000000000000..c9f8fded6c192
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfplan.json
@@ -0,0 +1,319 @@
+{
+ "format_version": "1.2",
+ "terraform_version": "1.12.2",
+ "planned_values": {
+ "root_module": {
+ "resources": [
+ {
+ "address": "coder_ai_task.a[0]",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "a",
+ "index": 0,
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "sensitive_values": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ },
+ {
+ "address": "coder_ai_task.b[0]",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "b",
+ "index": 0,
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "sensitive_values": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "resource_changes": [
+ {
+ "address": "coder_ai_task.a[0]",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "a",
+ "index": 0,
+ "provider_name": "registry.terraform.io/coder/coder",
+ "change": {
+ "actions": [
+ "create"
+ ],
+ "before": null,
+ "after": {
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "after_unknown": {
+ "id": true,
+ "sidebar_app": [
+ {}
+ ]
+ },
+ "before_sensitive": false,
+ "after_sensitive": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ }
+ },
+ {
+ "address": "coder_ai_task.b[0]",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "b",
+ "index": 0,
+ "provider_name": "registry.terraform.io/coder/coder",
+ "change": {
+ "actions": [
+ "create"
+ ],
+ "before": null,
+ "after": {
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "after_unknown": {
+ "id": true,
+ "sidebar_app": [
+ {}
+ ]
+ },
+ "before_sensitive": false,
+ "after_sensitive": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ }
+ }
+ ],
+ "prior_state": {
+ "format_version": "1.0",
+ "terraform_version": "1.12.2",
+ "values": {
+ "root_module": {
+ "resources": [
+ {
+ "address": "data.coder_parameter.prompt",
+ "mode": "data",
+ "type": "coder_parameter",
+ "name": "prompt",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "default": null,
+ "description": null,
+ "display_name": null,
+ "ephemeral": false,
+ "form_type": "input",
+ "icon": null,
+ "id": "f9502ef2-226e-49a6-8831-99a74f8415e7",
+ "mutable": false,
+ "name": "AI Prompt",
+ "option": null,
+ "optional": false,
+ "order": null,
+ "styling": "{}",
+ "type": "string",
+ "validation": [],
+ "value": ""
+ },
+ "sensitive_values": {
+ "validation": []
+ }
+ },
+ {
+ "address": "data.coder_provisioner.me",
+ "mode": "data",
+ "type": "coder_provisioner",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "arch": "amd64",
+ "id": "6b538d81-f0db-4e2b-8d85-4b87a1563d89",
+ "os": "linux"
+ },
+ "sensitive_values": {}
+ },
+ {
+ "address": "data.coder_workspace.me",
+ "mode": "data",
+ "type": "coder_workspace",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "access_port": 443,
+ "access_url": "https://dev.coder.com/",
+ "id": "344575c1-55b9-43bb-89b5-35f547e2cf08",
+ "is_prebuild": false,
+ "is_prebuild_claim": false,
+ "name": "sebenza-nonix",
+ "prebuild_count": 0,
+ "start_count": 1,
+ "template_id": "",
+ "template_name": "",
+ "template_version": "",
+ "transition": "start"
+ },
+ "sensitive_values": {}
+ },
+ {
+ "address": "data.coder_workspace_owner.me",
+ "mode": "data",
+ "type": "coder_workspace_owner",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 0,
+ "values": {
+ "email": "default@example.com",
+ "full_name": "default",
+ "groups": [],
+ "id": "acb465b5-2709-4392-9486-4ad6eb1c06e0",
+ "login_type": null,
+ "name": "default",
+ "oidc_access_token": "",
+ "rbac_roles": [],
+ "session_token": "",
+ "ssh_private_key": "",
+ "ssh_public_key": ""
+ },
+ "sensitive_values": {
+ "groups": [],
+ "rbac_roles": [],
+ "ssh_private_key": true
+ }
+ }
+ ]
+ }
+ }
+ },
+ "configuration": {
+ "provider_config": {
+ "coder": {
+ "name": "coder",
+ "full_name": "registry.terraform.io/coder/coder",
+ "version_constraint": ">= 2.0.0"
+ }
+ },
+ "root_module": {
+ "resources": [
+ {
+ "address": "coder_ai_task.a",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "a",
+ "provider_config_key": "coder",
+ "expressions": {
+ "sidebar_app": [
+ {
+ "id": {
+ "constant_value": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ }
+ ]
+ },
+ "schema_version": 1,
+ "count_expression": {
+ "constant_value": 1
+ }
+ },
+ {
+ "address": "coder_ai_task.b",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "b",
+ "provider_config_key": "coder",
+ "expressions": {
+ "sidebar_app": [
+ {
+ "id": {
+ "constant_value": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ }
+ ]
+ },
+ "schema_version": 1,
+ "count_expression": {
+ "constant_value": 1
+ }
+ },
+ {
+ "address": "data.coder_parameter.prompt",
+ "mode": "data",
+ "type": "coder_parameter",
+ "name": "prompt",
+ "provider_config_key": "coder",
+ "expressions": {
+ "name": {
+ "constant_value": "AI Prompt"
+ },
+ "type": {
+ "constant_value": "string"
+ }
+ },
+ "schema_version": 1
+ },
+ {
+ "address": "data.coder_provisioner.me",
+ "mode": "data",
+ "type": "coder_provisioner",
+ "name": "me",
+ "provider_config_key": "coder",
+ "schema_version": 1
+ },
+ {
+ "address": "data.coder_workspace.me",
+ "mode": "data",
+ "type": "coder_workspace",
+ "name": "me",
+ "provider_config_key": "coder",
+ "schema_version": 1
+ },
+ {
+ "address": "data.coder_workspace_owner.me",
+ "mode": "data",
+ "type": "coder_workspace_owner",
+ "name": "me",
+ "provider_config_key": "coder",
+ "schema_version": 0
+ }
+ ]
+ }
+ },
+ "timestamp": "2025-06-19T14:30:00Z",
+ "applyable": true,
+ "complete": true,
+ "errored": false
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfstate.dot b/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfstate.dot
new file mode 100644
index 0000000000000..4e660599e7a9b
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfstate.dot
@@ -0,0 +1,26 @@
+digraph {
+ compound = "true"
+ newrank = "true"
+ subgraph "root" {
+ "[root] coder_ai_task.a (expand)" [label = "coder_ai_task.a", shape = "box"]
+ "[root] coder_ai_task.b (expand)" [label = "coder_ai_task.b", shape = "box"]
+ "[root] data.coder_parameter.prompt (expand)" [label = "data.coder_parameter.prompt", shape = "box"]
+ "[root] data.coder_provisioner.me (expand)" [label = "data.coder_provisioner.me", shape = "box"]
+ "[root] data.coder_workspace.me (expand)" [label = "data.coder_workspace.me", shape = "box"]
+ "[root] data.coder_workspace_owner.me (expand)" [label = "data.coder_workspace_owner.me", shape = "box"]
+ "[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
+ "[root] coder_ai_task.a (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] coder_ai_task.b (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_parameter.prompt (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_provisioner.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_workspace.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] data.coder_workspace_owner.me (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_ai_task.a (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_ai_task.b (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_parameter.prompt (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_provisioner.me (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_workspace.me (expand)"
+ "[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] data.coder_workspace_owner.me (expand)"
+ "[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
+ }
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfstate.json b/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfstate.json
new file mode 100644
index 0000000000000..8eb9ccecd7636
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-multiple/ai-tasks-multiple.tfstate.json
@@ -0,0 +1,146 @@
+{
+ "format_version": "1.0",
+ "terraform_version": "1.12.2",
+ "values": {
+ "root_module": {
+ "resources": [
+ {
+ "address": "data.coder_parameter.prompt",
+ "mode": "data",
+ "type": "coder_parameter",
+ "name": "prompt",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "default": null,
+ "description": null,
+ "display_name": null,
+ "ephemeral": false,
+ "form_type": "input",
+ "icon": null,
+ "id": "d3c415c0-c6bc-42e3-806e-8c792a7e7b3b",
+ "mutable": false,
+ "name": "AI Prompt",
+ "option": null,
+ "optional": false,
+ "order": null,
+ "styling": "{}",
+ "type": "string",
+ "validation": [],
+ "value": ""
+ },
+ "sensitive_values": {
+ "validation": []
+ }
+ },
+ {
+ "address": "data.coder_provisioner.me",
+ "mode": "data",
+ "type": "coder_provisioner",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "arch": "amd64",
+ "id": "764f8b0b-d931-4356-b1a8-446fa95fbeb0",
+ "os": "linux"
+ },
+ "sensitive_values": {}
+ },
+ {
+ "address": "data.coder_workspace.me",
+ "mode": "data",
+ "type": "coder_workspace",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "access_port": 443,
+ "access_url": "https://dev.coder.com/",
+ "id": "b6713709-6736-4d2f-b3da-7b5b242df5f4",
+ "is_prebuild": false,
+ "is_prebuild_claim": false,
+ "name": "sebenza-nonix",
+ "prebuild_count": 0,
+ "start_count": 1,
+ "template_id": "",
+ "template_name": "",
+ "template_version": "",
+ "transition": "start"
+ },
+ "sensitive_values": {}
+ },
+ {
+ "address": "data.coder_workspace_owner.me",
+ "mode": "data",
+ "type": "coder_workspace_owner",
+ "name": "me",
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 0,
+ "values": {
+ "email": "default@example.com",
+ "full_name": "default",
+ "groups": [],
+ "id": "0cc15fa2-24fc-4249-bdc7-56cf0af0f782",
+ "login_type": null,
+ "name": "default",
+ "oidc_access_token": "",
+ "rbac_roles": [],
+ "session_token": "",
+ "ssh_private_key": "",
+ "ssh_public_key": ""
+ },
+ "sensitive_values": {
+ "groups": [],
+ "rbac_roles": [],
+ "ssh_private_key": true
+ }
+ },
+ {
+ "address": "coder_ai_task.a[0]",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "a",
+ "index": 0,
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "id": "89e6ab36-2e98-4d13-9b4c-69b7588b7e1d",
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "sensitive_values": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ },
+ {
+ "address": "coder_ai_task.b[0]",
+ "mode": "managed",
+ "type": "coder_ai_task",
+ "name": "b",
+ "index": 0,
+ "provider_name": "registry.terraform.io/coder/coder",
+ "schema_version": 1,
+ "values": {
+ "id": "d4643699-519d-44c8-a878-556789256cbd",
+ "sidebar_app": [
+ {
+ "id": "5ece4674-dd35-4f16-88c8-82e40e72e2fd"
+ }
+ ]
+ },
+ "sensitive_values": {
+ "sidebar_app": [
+ {}
+ ]
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/provisioner/terraform/testdata/resources/ai-tasks-multiple/main.tf b/provisioner/terraform/testdata/resources/ai-tasks-multiple/main.tf
new file mode 100644
index 0000000000000..6c15ee4dc5a69
--- /dev/null
+++ b/provisioner/terraform/testdata/resources/ai-tasks-multiple/main.tf
@@ -0,0 +1,31 @@
+terraform {
+ required_providers {
+ coder = {
+ source = "coder/coder"
+ version = ">= 2.0.0"
+ }
+ }
+}
+
+data "coder_provisioner" "me" {}
+data "coder_workspace" "me" {}
+data "coder_workspace_owner" "me" {}
+
+data "coder_parameter" "prompt" {
+ name = "AI Prompt"
+ type = "string"
+}
+
+resource "coder_ai_task" "a" {
+ count = 1
+ sidebar_app {
+ id = "5ece4674-dd35-4f16-88c8-82e40e72e2fd" # fake ID to satisfy requirement, irrelevant otherwise
+ }
+}
+
+resource "coder_ai_task" "b" {
+ count = 1
+ sidebar_app {
+ id = "5ece4674-dd35-4f16-88c8-82e40e72e2fd" # fake ID to satisfy requirement, irrelevant otherwise
+ }
+}
diff --git a/provisionerd/proto/provisionerd.pb.go b/provisionerd/proto/provisionerd.pb.go
index b4343eafbfdac..9960105c78962 100644
--- a/provisionerd/proto/provisionerd.pb.go
+++ b/provisionerd/proto/provisionerd.pb.go
@@ -1309,6 +1309,7 @@ type CompletedJob_WorkspaceBuild struct {
Timings []*proto.Timing `protobuf:"bytes,3,rep,name=timings,proto3" json:"timings,omitempty"`
Modules []*proto.Module `protobuf:"bytes,4,rep,name=modules,proto3" json:"modules,omitempty"`
ResourceReplacements []*proto.ResourceReplacement `protobuf:"bytes,5,rep,name=resource_replacements,json=resourceReplacements,proto3" json:"resource_replacements,omitempty"`
+ AiTasks []*proto.AITask `protobuf:"bytes,6,rep,name=ai_tasks,json=aiTasks,proto3" json:"ai_tasks,omitempty"`
}
func (x *CompletedJob_WorkspaceBuild) Reset() {
@@ -1378,6 +1379,13 @@ func (x *CompletedJob_WorkspaceBuild) GetResourceReplacements() []*proto.Resourc
return nil
}
+func (x *CompletedJob_WorkspaceBuild) GetAiTasks() []*proto.AITask {
+ if x != nil {
+ return x.AiTasks
+ }
+ return nil
+}
+
type CompletedJob_TemplateImport struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1394,6 +1402,7 @@ type CompletedJob_TemplateImport struct {
Plan []byte `protobuf:"bytes,9,opt,name=plan,proto3" json:"plan,omitempty"`
ModuleFiles []byte `protobuf:"bytes,10,opt,name=module_files,json=moduleFiles,proto3" json:"module_files,omitempty"`
ModuleFilesHash []byte `protobuf:"bytes,11,opt,name=module_files_hash,json=moduleFilesHash,proto3" json:"module_files_hash,omitempty"`
+ HasAiTasks bool `protobuf:"varint,12,opt,name=has_ai_tasks,json=hasAiTasks,proto3" json:"has_ai_tasks,omitempty"`
}
func (x *CompletedJob_TemplateImport) Reset() {
@@ -1505,6 +1514,13 @@ func (x *CompletedJob_TemplateImport) GetModuleFilesHash() []byte {
return nil
}
+func (x *CompletedJob_TemplateImport) GetHasAiTasks() bool {
+ if x != nil {
+ return x.HasAiTasks
+ }
+ return false
+}
+
type CompletedJob_TemplateDryRun struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1694,7 +1710,7 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
0x6d, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x10, 0x0a,
0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a,
0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75,
- 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb9, 0x0a, 0x0a, 0x0c, 0x43, 0x6f,
+ 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x8b, 0x0b, 0x0a, 0x0c, 0x43, 0x6f,
0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f,
0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49,
0x64, 0x12, 0x54, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62,
@@ -1713,7 +1729,7 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64,
0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52,
0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72,
- 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x90, 0x02, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
+ 0x79, 0x52, 0x75, 0x6e, 0x1a, 0xc0, 0x02, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a,
0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
@@ -1730,7 +1746,10 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e,
0x74, 0x52, 0x14, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61,
- 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0xfd, 0x04, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70,
+ 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x61, 0x69, 0x5f, 0x74, 0x61,
+ 0x73, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x49, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x07,
+ 0x61, 0x69, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x1a, 0x9f, 0x05, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70,
0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3e, 0x0a, 0x0f, 0x73, 0x74,
0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
@@ -1770,122 +1789,124 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d,
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68,
0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69,
- 0x6c, 0x65, 0x73, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x74, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c,
- 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73,
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70,
- 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
- 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2d,
- 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f,
- 0x64, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x06, 0x0a,
- 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x2f, 0x0a,
- 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e,
- 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67,
- 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2b,
- 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e,
- 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x4c,
- 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63,
- 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
- 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65,
- 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xa6, 0x03, 0x0a, 0x10, 0x55, 0x70, 0x64,
- 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a,
- 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a,
- 0x6f, 0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
- 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x4c, 0x0a, 0x12, 0x74,
- 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
- 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61,
- 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
- 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x14, 0x75, 0x73, 0x65,
- 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
- 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
- 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d,
- 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x12,
- 0x58, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x67,
- 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
- 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b,
- 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x1a, 0x40, 0x0a, 0x12, 0x57, 0x6f, 0x72,
- 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
- 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
- 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x03, 0x10,
- 0x04, 0x22, 0x7a, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c,
- 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c,
- 0x65, 0x64, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72,
- 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
- 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
- 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0x4a, 0x0a,
- 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61,
- 0x69, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09,
- 0x64, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x68, 0x0a, 0x13, 0x43, 0x6f, 0x6d,
- 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b,
- 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73,
- 0x75, 0x6d, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x64,
- 0x69, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62,
- 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x75, 0x64,
- 0x67, 0x65, 0x74, 0x22, 0x0f, 0x0a, 0x0d, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x63, 0x71,
- 0x75, 0x69, 0x72, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46,
- 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0b, 0x64, 0x61,
- 0x74, 0x61, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x44, 0x61,
- 0x74, 0x61, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61,
- 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3a, 0x0a, 0x0b, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f,
- 0x70, 0x69, 0x65, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72,
- 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x50,
- 0x69, 0x65, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x69, 0x65,
- 0x63, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x34, 0x0a, 0x09, 0x4c, 0x6f,
- 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x56, 0x49,
- 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x10, 0x00, 0x12,
- 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x10, 0x01,
- 0x32, 0x8b, 0x04, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
- 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0a, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72,
- 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65,
- 0x64, 0x4a, 0x6f, 0x62, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x52, 0x0a, 0x14, 0x41, 0x63, 0x71,
- 0x75, 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62, 0x57, 0x69, 0x74, 0x68, 0x43, 0x61, 0x6e, 0x63, 0x65,
- 0x6c, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64,
- 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x1a, 0x19,
- 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63,
- 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x28, 0x01, 0x30, 0x01, 0x12, 0x52, 0x0a,
- 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x20, 0x2e, 0x70,
- 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
- 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
+ 0x6c, 0x65, 0x73, 0x48, 0x61, 0x73, 0x68, 0x12, 0x20, 0x0a, 0x0c, 0x68, 0x61, 0x73, 0x5f, 0x61,
+ 0x69, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x68,
+ 0x61, 0x73, 0x41, 0x69, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x1a, 0x74, 0x0a, 0x0e, 0x54, 0x65, 0x6d,
+ 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x33, 0x0a, 0x09, 0x72,
+ 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15,
+ 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
+ 0x12, 0x2d, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x42,
+ 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12,
+ 0x2f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x4c,
+ 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+ 0x12, 0x2b, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f,
+ 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a,
+ 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05,
+ 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61,
+ 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xa6, 0x03, 0x0a, 0x10, 0x55,
+ 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+ 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+ 0x65, 0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x4c, 0x0a,
+ 0x12, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x14, 0x75,
+ 0x73, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61,
+ 0x64, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d,
+ 0x65, 0x12, 0x58, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74,
+ 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a,
+ 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
+ 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x77, 0x6f,
+ 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x1a, 0x40, 0x0a, 0x12, 0x57,
+ 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
+ 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08,
+ 0x03, 0x10, 0x04, 0x22, 0x7a, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x6e, 0x63,
+ 0x65, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x61, 0x6e, 0x63,
+ 0x65, 0x6c, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
+ 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+ 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22,
+ 0x4a, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
+ 0x64, 0x61, 0x69, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x09, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x68, 0x0a, 0x13, 0x43,
+ 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02,
+ 0x6f, 0x6b, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x5f, 0x63, 0x6f,
+ 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x72,
+ 0x65, 0x64, 0x69, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x16, 0x0a,
+ 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62,
+ 0x75, 0x64, 0x67, 0x65, 0x74, 0x22, 0x0f, 0x0a, 0x0d, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41,
+ 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61,
+ 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0b,
+ 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
+ 0x44, 0x61, 0x74, 0x61, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x0a, 0x64, 0x61,
+ 0x74, 0x61, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3a, 0x0a, 0x0b, 0x63, 0x68, 0x75, 0x6e,
+ 0x6b, 0x5f, 0x70, 0x69, 0x65, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
+ 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x43, 0x68, 0x75, 0x6e,
+ 0x6b, 0x50, 0x69, 0x65, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x50,
+ 0x69, 0x65, 0x63, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x34, 0x0a, 0x09,
+ 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f,
+ 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x10,
+ 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52,
+ 0x10, 0x01, 0x32, 0x8b, 0x04, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+ 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0a, 0x41, 0x63, 0x71, 0x75,
+ 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
+ 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x70, 0x72,
+ 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69,
+ 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x52, 0x0a, 0x14, 0x41,
+ 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62, 0x57, 0x69, 0x74, 0x68, 0x43, 0x61, 0x6e,
+ 0x63, 0x65, 0x6c, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
+ 0x72, 0x64, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65,
+ 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
+ 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x28, 0x01, 0x30, 0x01, 0x12,
+ 0x52, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x20,
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f,
- 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1e,
- 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70,
- 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f,
- 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70,
- 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
- 0x37, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f,
- 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64,
- 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
- 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70,
- 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64,
- 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
- 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f,
- 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x42, 0x2e,
- 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64,
- 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x76,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
+ 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62,
+ 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x12, 0x37, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x70,
+ 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c,
+ 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
+ 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0b, 0x43, 0x6f,
+ 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74,
+ 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
+ 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0a, 0x55, 0x70,
+ 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
+ 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69,
+ 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01,
+ 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72,
+ 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1938,9 +1959,10 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{
(*proto.Resource)(nil), // 32: provisioner.Resource
(*proto.Module)(nil), // 33: provisioner.Module
(*proto.ResourceReplacement)(nil), // 34: provisioner.ResourceReplacement
- (*proto.RichParameter)(nil), // 35: provisioner.RichParameter
- (*proto.ExternalAuthProviderResource)(nil), // 36: provisioner.ExternalAuthProviderResource
- (*proto.Preset)(nil), // 37: provisioner.Preset
+ (*proto.AITask)(nil), // 35: provisioner.AITask
+ (*proto.RichParameter)(nil), // 36: provisioner.RichParameter
+ (*proto.ExternalAuthProviderResource)(nil), // 37: provisioner.ExternalAuthProviderResource
+ (*proto.Preset)(nil), // 38: provisioner.Preset
}
var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{
12, // 0: provisionerd.AcquiredJob.workspace_build:type_name -> provisionerd.AcquiredJob.WorkspaceBuild
@@ -1977,34 +1999,35 @@ var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{
31, // 31: provisionerd.CompletedJob.WorkspaceBuild.timings:type_name -> provisioner.Timing
33, // 32: provisionerd.CompletedJob.WorkspaceBuild.modules:type_name -> provisioner.Module
34, // 33: provisionerd.CompletedJob.WorkspaceBuild.resource_replacements:type_name -> provisioner.ResourceReplacement
- 32, // 34: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource
- 32, // 35: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource
- 35, // 36: provisionerd.CompletedJob.TemplateImport.rich_parameters:type_name -> provisioner.RichParameter
- 36, // 37: provisionerd.CompletedJob.TemplateImport.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource
- 33, // 38: provisionerd.CompletedJob.TemplateImport.start_modules:type_name -> provisioner.Module
- 33, // 39: provisionerd.CompletedJob.TemplateImport.stop_modules:type_name -> provisioner.Module
- 37, // 40: provisionerd.CompletedJob.TemplateImport.presets:type_name -> provisioner.Preset
- 32, // 41: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource
- 33, // 42: provisionerd.CompletedJob.TemplateDryRun.modules:type_name -> provisioner.Module
- 1, // 43: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty
- 10, // 44: provisionerd.ProvisionerDaemon.AcquireJobWithCancel:input_type -> provisionerd.CancelAcquire
- 8, // 45: provisionerd.ProvisionerDaemon.CommitQuota:input_type -> provisionerd.CommitQuotaRequest
- 6, // 46: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest
- 3, // 47: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob
- 4, // 48: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob
- 11, // 49: provisionerd.ProvisionerDaemon.UploadFile:input_type -> provisionerd.UploadFileRequest
- 2, // 50: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob
- 2, // 51: provisionerd.ProvisionerDaemon.AcquireJobWithCancel:output_type -> provisionerd.AcquiredJob
- 9, // 52: provisionerd.ProvisionerDaemon.CommitQuota:output_type -> provisionerd.CommitQuotaResponse
- 7, // 53: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse
- 1, // 54: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty
- 1, // 55: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty
- 1, // 56: provisionerd.ProvisionerDaemon.UploadFile:output_type -> provisionerd.Empty
- 50, // [50:57] is the sub-list for method output_type
- 43, // [43:50] is the sub-list for method input_type
- 43, // [43:43] is the sub-list for extension type_name
- 43, // [43:43] is the sub-list for extension extendee
- 0, // [0:43] is the sub-list for field type_name
+ 35, // 34: provisionerd.CompletedJob.WorkspaceBuild.ai_tasks:type_name -> provisioner.AITask
+ 32, // 35: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource
+ 32, // 36: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource
+ 36, // 37: provisionerd.CompletedJob.TemplateImport.rich_parameters:type_name -> provisioner.RichParameter
+ 37, // 38: provisionerd.CompletedJob.TemplateImport.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource
+ 33, // 39: provisionerd.CompletedJob.TemplateImport.start_modules:type_name -> provisioner.Module
+ 33, // 40: provisionerd.CompletedJob.TemplateImport.stop_modules:type_name -> provisioner.Module
+ 38, // 41: provisionerd.CompletedJob.TemplateImport.presets:type_name -> provisioner.Preset
+ 32, // 42: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource
+ 33, // 43: provisionerd.CompletedJob.TemplateDryRun.modules:type_name -> provisioner.Module
+ 1, // 44: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty
+ 10, // 45: provisionerd.ProvisionerDaemon.AcquireJobWithCancel:input_type -> provisionerd.CancelAcquire
+ 8, // 46: provisionerd.ProvisionerDaemon.CommitQuota:input_type -> provisionerd.CommitQuotaRequest
+ 6, // 47: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest
+ 3, // 48: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob
+ 4, // 49: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob
+ 11, // 50: provisionerd.ProvisionerDaemon.UploadFile:input_type -> provisionerd.UploadFileRequest
+ 2, // 51: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob
+ 2, // 52: provisionerd.ProvisionerDaemon.AcquireJobWithCancel:output_type -> provisionerd.AcquiredJob
+ 9, // 53: provisionerd.ProvisionerDaemon.CommitQuota:output_type -> provisionerd.CommitQuotaResponse
+ 7, // 54: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse
+ 1, // 55: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty
+ 1, // 56: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty
+ 1, // 57: provisionerd.ProvisionerDaemon.UploadFile:output_type -> provisionerd.Empty
+ 51, // [51:58] is the sub-list for method output_type
+ 44, // [44:51] is the sub-list for method input_type
+ 44, // [44:44] is the sub-list for extension type_name
+ 44, // [44:44] is the sub-list for extension extendee
+ 0, // [0:44] is the sub-list for field type_name
}
func init() { file_provisionerd_proto_provisionerd_proto_init() }
diff --git a/provisionerd/proto/provisionerd.proto b/provisionerd/proto/provisionerd.proto
index 1b5ede6e13c71..eeeb5f02da0fb 100644
--- a/provisionerd/proto/provisionerd.proto
+++ b/provisionerd/proto/provisionerd.proto
@@ -80,6 +80,7 @@ message CompletedJob {
repeated provisioner.Timing timings = 3;
repeated provisioner.Module modules = 4;
repeated provisioner.ResourceReplacement resource_replacements = 5;
+ repeated provisioner.AITask ai_tasks = 6;
}
message TemplateImport {
repeated provisioner.Resource start_resources = 1;
@@ -93,6 +94,7 @@ message CompletedJob {
bytes plan = 9;
bytes module_files = 10;
bytes module_files_hash = 11;
+ bool has_ai_tasks = 12;
}
message TemplateDryRun {
repeated provisioner.Resource resources = 1;
diff --git a/provisionerd/proto/version.go b/provisionerd/proto/version.go
index 8edffb342fb8a..e61aac0c5abd8 100644
--- a/provisionerd/proto/version.go
+++ b/provisionerd/proto/version.go
@@ -39,6 +39,11 @@ import "github.com/coder/coder/v2/apiversion"
// instances based on time patterns.
// - Added new field named `id` to `App`, which transports the ID generated by the coder_app provider to be persisted.
// - Added new field named `default` to `Preset`.
+// - Added various fields in support of AI Tasks:
+// -> `ai_tasks` in `CompleteJob.WorkspaceBuild`
+// -> `has_ai_tasks` in `CompleteJob.TemplateImport`
+// -> `has_ai_tasks` and `ai_tasks` in `PlanComplete`
+// -> new message types `AITaskSidebarApp` and `AITask`
const (
CurrentMajor = 1
CurrentMinor = 7
diff --git a/provisionerd/runner/runner.go b/provisionerd/runner/runner.go
index 305bd2543dd82..b80cf9060b358 100644
--- a/provisionerd/runner/runner.go
+++ b/provisionerd/runner/runner.go
@@ -584,8 +584,6 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
externalAuthProviderNames = append(externalAuthProviderNames, it.Id)
}
- // fmt.Println("completed job: template import: graph:", startProvision.Graph)
-
return &proto.CompletedJob{
JobId: r.job.JobId,
Type: &proto.CompletedJob_TemplateImport_{
@@ -603,6 +601,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
ModuleFiles: startProvision.ModuleFiles,
// ModuleFileHash will be populated if the file is uploaded async
ModuleFilesHash: []byte{},
+ HasAiTasks: startProvision.HasAITasks,
},
},
}, nil
@@ -666,6 +665,7 @@ type templateImportProvision struct {
Presets []*sdkproto.Preset
Plan json.RawMessage
ModuleFiles []byte
+ HasAITasks bool
}
// Performs a dry-run provision when importing a template.
@@ -798,7 +798,6 @@ func (r *Runner) runTemplateImportProvisionWithRichParameters(
return nil, xerrors.Errorf("module files hash mismatch, uploaded: %x, expected: %x", moduleFilesUpload.Hash, c.ModuleFilesHash)
}
}
-
return &templateImportProvision{
Resources: c.Resources,
Parameters: c.Parameters,
@@ -807,6 +806,7 @@ func (r *Runner) runTemplateImportProvisionWithRichParameters(
Presets: c.Presets,
Plan: c.Plan,
ModuleFiles: moduleFilesData,
+ HasAITasks: c.HasAiTasks,
}, nil
default:
return nil, xerrors.Errorf("invalid message type %q received from provisioner",
@@ -1047,6 +1047,9 @@ func (r *Runner) runWorkspaceBuild(ctx context.Context) (*proto.CompletedJob, *p
},
}
}
+ if len(planComplete.AiTasks) > 1 {
+ return nil, r.failedWorkspaceBuildf("only one 'coder_ai_task' resource can be provisioned per template")
+ }
r.logger.Info(context.Background(), "plan request successful",
slog.F("resource_count", len(planComplete.Resources)),
@@ -1124,6 +1127,7 @@ func (r *Runner) runWorkspaceBuild(ctx context.Context) (*proto.CompletedJob, *p
Modules: planComplete.Modules,
// Resource replacements are discovered at plan time, only.
ResourceReplacements: planComplete.ResourceReplacements,
+ AiTasks: applyComplete.AiTasks,
},
},
}, nil
diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go
index 0e6595862db40..7412cb6155610 100644
--- a/provisionersdk/proto/provisioner.pb.go
+++ b/provisionersdk/proto/provisioner.pb.go
@@ -2783,6 +2783,108 @@ func (x *RunningAgentAuthToken) GetToken() string {
return ""
}
+type AITaskSidebarApp struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+}
+
+func (x *AITaskSidebarApp) Reset() {
+ *x = AITaskSidebarApp{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AITaskSidebarApp) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AITaskSidebarApp) ProtoMessage() {}
+
+func (x *AITaskSidebarApp) ProtoReflect() protoreflect.Message {
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AITaskSidebarApp.ProtoReflect.Descriptor instead.
+func (*AITaskSidebarApp) Descriptor() ([]byte, []int) {
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{31}
+}
+
+func (x *AITaskSidebarApp) GetId() string {
+ if x != nil {
+ return x.Id
+ }
+ return ""
+}
+
+type AITask struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+ SidebarApp *AITaskSidebarApp `protobuf:"bytes,2,opt,name=sidebar_app,json=sidebarApp,proto3" json:"sidebar_app,omitempty"`
+}
+
+func (x *AITask) Reset() {
+ *x = AITask{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AITask) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AITask) ProtoMessage() {}
+
+func (x *AITask) ProtoReflect() protoreflect.Message {
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AITask.ProtoReflect.Descriptor instead.
+func (*AITask) Descriptor() ([]byte, []int) {
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{32}
+}
+
+func (x *AITask) GetId() string {
+ if x != nil {
+ return x.Id
+ }
+ return ""
+}
+
+func (x *AITask) GetSidebarApp() *AITaskSidebarApp {
+ if x != nil {
+ return x.SidebarApp
+ }
+ return nil
+}
+
// Metadata is information about a workspace used in the execution of a build
type Metadata struct {
state protoimpl.MessageState
@@ -2815,7 +2917,7 @@ type Metadata struct {
func (x *Metadata) Reset() {
*x = Metadata{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2828,7 +2930,7 @@ func (x *Metadata) String() string {
func (*Metadata) ProtoMessage() {}
func (x *Metadata) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[33]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2841,7 +2943,7 @@ func (x *Metadata) ProtoReflect() protoreflect.Message {
// Deprecated: Use Metadata.ProtoReflect.Descriptor instead.
func (*Metadata) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{31}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{33}
}
func (x *Metadata) GetCoderUrl() string {
@@ -3007,7 +3109,7 @@ type Config struct {
func (x *Config) Reset() {
*x = Config{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3020,7 +3122,7 @@ func (x *Config) String() string {
func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[34]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3033,7 +3135,7 @@ func (x *Config) ProtoReflect() protoreflect.Message {
// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{32}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{34}
}
func (x *Config) GetTemplateSourceArchive() []byte {
@@ -3067,7 +3169,7 @@ type ParseRequest struct {
func (x *ParseRequest) Reset() {
*x = ParseRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[33]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3080,7 +3182,7 @@ func (x *ParseRequest) String() string {
func (*ParseRequest) ProtoMessage() {}
func (x *ParseRequest) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[33]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[35]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3093,7 +3195,7 @@ func (x *ParseRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ParseRequest.ProtoReflect.Descriptor instead.
func (*ParseRequest) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{33}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{35}
}
// ParseComplete indicates a request to parse completed.
@@ -3111,7 +3213,7 @@ type ParseComplete struct {
func (x *ParseComplete) Reset() {
*x = ParseComplete{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[34]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3124,7 +3226,7 @@ func (x *ParseComplete) String() string {
func (*ParseComplete) ProtoMessage() {}
func (x *ParseComplete) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[34]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[36]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3137,7 +3239,7 @@ func (x *ParseComplete) ProtoReflect() protoreflect.Message {
// Deprecated: Use ParseComplete.ProtoReflect.Descriptor instead.
func (*ParseComplete) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{34}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{36}
}
func (x *ParseComplete) GetError() string {
@@ -3190,7 +3292,7 @@ type PlanRequest struct {
func (x *PlanRequest) Reset() {
*x = PlanRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[35]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3203,7 +3305,7 @@ func (x *PlanRequest) String() string {
func (*PlanRequest) ProtoMessage() {}
func (x *PlanRequest) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[35]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[37]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3216,7 +3318,7 @@ func (x *PlanRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use PlanRequest.ProtoReflect.Descriptor instead.
func (*PlanRequest) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{35}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{37}
}
func (x *PlanRequest) GetMetadata() *Metadata {
@@ -3278,12 +3380,19 @@ type PlanComplete struct {
ResourceReplacements []*ResourceReplacement `protobuf:"bytes,10,rep,name=resource_replacements,json=resourceReplacements,proto3" json:"resource_replacements,omitempty"`
ModuleFiles []byte `protobuf:"bytes,11,opt,name=module_files,json=moduleFiles,proto3" json:"module_files,omitempty"`
ModuleFilesHash []byte `protobuf:"bytes,12,opt,name=module_files_hash,json=moduleFilesHash,proto3" json:"module_files_hash,omitempty"`
+ // Whether a template has any `coder_ai_task` resources defined, even if not planned for creation.
+ // During a template import, a plan is run which may not yield in any `coder_ai_task` resources, but nonetheless we
+ // still need to know that such resources are defined.
+ //
+ // See `hasAITaskResources` in provisioner/terraform/resources.go for more details.
+ HasAiTasks bool `protobuf:"varint,13,opt,name=has_ai_tasks,json=hasAiTasks,proto3" json:"has_ai_tasks,omitempty"`
+ AiTasks []*AITask `protobuf:"bytes,14,rep,name=ai_tasks,json=aiTasks,proto3" json:"ai_tasks,omitempty"`
}
func (x *PlanComplete) Reset() {
*x = PlanComplete{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[36]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[38]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3296,7 +3405,7 @@ func (x *PlanComplete) String() string {
func (*PlanComplete) ProtoMessage() {}
func (x *PlanComplete) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[36]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[38]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3309,7 +3418,7 @@ func (x *PlanComplete) ProtoReflect() protoreflect.Message {
// Deprecated: Use PlanComplete.ProtoReflect.Descriptor instead.
func (*PlanComplete) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{36}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{38}
}
func (x *PlanComplete) GetError() string {
@@ -3389,6 +3498,20 @@ func (x *PlanComplete) GetModuleFilesHash() []byte {
return nil
}
+func (x *PlanComplete) GetHasAiTasks() bool {
+ if x != nil {
+ return x.HasAiTasks
+ }
+ return false
+}
+
+func (x *PlanComplete) GetAiTasks() []*AITask {
+ if x != nil {
+ return x.AiTasks
+ }
+ return nil
+}
+
// ApplyRequest asks the provisioner to apply the changes. Apply MUST be preceded by a successful plan request/response
// in the same Session. The plan data is not transmitted over the wire and is cached by the provisioner in the Session.
type ApplyRequest struct {
@@ -3402,7 +3525,7 @@ type ApplyRequest struct {
func (x *ApplyRequest) Reset() {
*x = ApplyRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[37]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3415,7 +3538,7 @@ func (x *ApplyRequest) String() string {
func (*ApplyRequest) ProtoMessage() {}
func (x *ApplyRequest) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[37]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[39]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3428,7 +3551,7 @@ func (x *ApplyRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ApplyRequest.ProtoReflect.Descriptor instead.
func (*ApplyRequest) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{37}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{39}
}
func (x *ApplyRequest) GetMetadata() *Metadata {
@@ -3450,12 +3573,13 @@ type ApplyComplete struct {
Parameters []*RichParameter `protobuf:"bytes,4,rep,name=parameters,proto3" json:"parameters,omitempty"`
ExternalAuthProviders []*ExternalAuthProviderResource `protobuf:"bytes,5,rep,name=external_auth_providers,json=externalAuthProviders,proto3" json:"external_auth_providers,omitempty"`
Timings []*Timing `protobuf:"bytes,6,rep,name=timings,proto3" json:"timings,omitempty"`
+ AiTasks []*AITask `protobuf:"bytes,7,rep,name=ai_tasks,json=aiTasks,proto3" json:"ai_tasks,omitempty"`
}
func (x *ApplyComplete) Reset() {
*x = ApplyComplete{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[38]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3468,7 +3592,7 @@ func (x *ApplyComplete) String() string {
func (*ApplyComplete) ProtoMessage() {}
func (x *ApplyComplete) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[38]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[40]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3481,7 +3605,7 @@ func (x *ApplyComplete) ProtoReflect() protoreflect.Message {
// Deprecated: Use ApplyComplete.ProtoReflect.Descriptor instead.
func (*ApplyComplete) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{38}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{40}
}
func (x *ApplyComplete) GetState() []byte {
@@ -3526,6 +3650,13 @@ func (x *ApplyComplete) GetTimings() []*Timing {
return nil
}
+func (x *ApplyComplete) GetAiTasks() []*AITask {
+ if x != nil {
+ return x.AiTasks
+ }
+ return nil
+}
+
type Timing struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -3543,7 +3674,7 @@ type Timing struct {
func (x *Timing) Reset() {
*x = Timing{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[39]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3556,7 +3687,7 @@ func (x *Timing) String() string {
func (*Timing) ProtoMessage() {}
func (x *Timing) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[39]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[41]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3569,7 +3700,7 @@ func (x *Timing) ProtoReflect() protoreflect.Message {
// Deprecated: Use Timing.ProtoReflect.Descriptor instead.
func (*Timing) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{39}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{41}
}
func (x *Timing) GetStart() *timestamppb.Timestamp {
@@ -3631,7 +3762,7 @@ type CancelRequest struct {
func (x *CancelRequest) Reset() {
*x = CancelRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[40]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[42]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3644,7 +3775,7 @@ func (x *CancelRequest) String() string {
func (*CancelRequest) ProtoMessage() {}
func (x *CancelRequest) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[40]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[42]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3657,7 +3788,7 @@ func (x *CancelRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CancelRequest.ProtoReflect.Descriptor instead.
func (*CancelRequest) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{40}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{42}
}
type Request struct {
@@ -3678,7 +3809,7 @@ type Request struct {
func (x *Request) Reset() {
*x = Request{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[41]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[43]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3691,7 +3822,7 @@ func (x *Request) String() string {
func (*Request) ProtoMessage() {}
func (x *Request) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[41]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[43]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3704,7 +3835,7 @@ func (x *Request) ProtoReflect() protoreflect.Message {
// Deprecated: Use Request.ProtoReflect.Descriptor instead.
func (*Request) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{41}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{43}
}
func (m *Request) GetType() isRequest_Type {
@@ -3802,7 +3933,7 @@ type Response struct {
func (x *Response) Reset() {
*x = Response{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[42]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[44]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3815,7 +3946,7 @@ func (x *Response) String() string {
func (*Response) ProtoMessage() {}
func (x *Response) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[42]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[44]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3828,7 +3959,7 @@ func (x *Response) ProtoReflect() protoreflect.Message {
// Deprecated: Use Response.ProtoReflect.Descriptor instead.
func (*Response) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{42}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{44}
}
func (m *Response) GetType() isResponse_Type {
@@ -3938,7 +4069,7 @@ type DataUpload struct {
func (x *DataUpload) Reset() {
*x = DataUpload{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[43]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[45]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3951,7 +4082,7 @@ func (x *DataUpload) String() string {
func (*DataUpload) ProtoMessage() {}
func (x *DataUpload) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[43]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[45]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3964,7 +4095,7 @@ func (x *DataUpload) ProtoReflect() protoreflect.Message {
// Deprecated: Use DataUpload.ProtoReflect.Descriptor instead.
func (*DataUpload) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{43}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{45}
}
func (x *DataUpload) GetUploadType() DataUploadType {
@@ -4011,7 +4142,7 @@ type ChunkPiece struct {
func (x *ChunkPiece) Reset() {
*x = ChunkPiece{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[44]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[46]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4024,7 +4155,7 @@ func (x *ChunkPiece) String() string {
func (*ChunkPiece) ProtoMessage() {}
func (x *ChunkPiece) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[44]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[46]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4037,7 +4168,7 @@ func (x *ChunkPiece) ProtoReflect() protoreflect.Message {
// Deprecated: Use ChunkPiece.ProtoReflect.Descriptor instead.
func (*ChunkPiece) Descriptor() ([]byte, []int) {
- return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{44}
+ return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{46}
}
func (x *ChunkPiece) GetData() []byte {
@@ -4077,7 +4208,7 @@ type Agent_Metadata struct {
func (x *Agent_Metadata) Reset() {
*x = Agent_Metadata{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[45]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[47]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4090,7 +4221,7 @@ func (x *Agent_Metadata) String() string {
func (*Agent_Metadata) ProtoMessage() {}
func (x *Agent_Metadata) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[45]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[47]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4162,7 +4293,7 @@ type Resource_Metadata struct {
func (x *Resource_Metadata) Reset() {
*x = Resource_Metadata{}
if protoimpl.UnsafeEnabled {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[47]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[49]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4175,7 +4306,7 @@ func (x *Resource_Metadata) String() string {
func (*Resource_Metadata) ProtoMessage() {}
func (x *Resource_Metadata) ProtoReflect() protoreflect.Message {
- mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[47]
+ mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[49]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4564,180 +4695,193 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{
0x65, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a,
0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f,
- 0x6b, 0x65, 0x6e, 0x22, 0xca, 0x09, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
- 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x53, 0x0a,
- 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73,
- 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x72,
- 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
- 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77,
- 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69,
- 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
- 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b,
- 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x6f, 0x72,
- 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e,
- 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
- 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70,
- 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
- 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65,
- 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
- 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e,
- 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c,
- 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
- 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10,
- 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
- 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x21, 0x77, 0x6f, 0x72, 0x6b, 0x73,
- 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x69, 0x64, 0x63, 0x5f,
- 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x1d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e,
- 0x65, 0x72, 0x4f, 0x69, 0x64, 0x63, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
- 0x6e, 0x12, 0x41, 0x0a, 0x1d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f,
- 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b,
- 0x65, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70,
- 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54,
- 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
- 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c,
- 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
- 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77,
- 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x73,
- 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70,
- 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
- 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x42, 0x0a,
- 0x1e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72,
- 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18,
- 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
- 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x53, 0x73, 0x68, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
- 0x79, 0x12, 0x44, 0x0a, 0x1f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f,
- 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
- 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1b, 0x77, 0x6f, 0x72, 0x6b,
- 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x53, 0x73, 0x68, 0x50, 0x72, 0x69,
- 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73,
- 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
- 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x74,
- 0x79, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x73,
- 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x79,
- 0x70, 0x65, 0x12, 0x4e, 0x0a, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
- 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x62, 0x61, 0x63, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73,
- 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x73,
- 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x62, 0x61, 0x63, 0x52, 0x6f, 0x6c,
- 0x65, 0x73, 0x12, 0x6d, 0x0a, 0x1e, 0x70, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x5f, 0x77,
- 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73,
- 0x74, 0x61, 0x67, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f,
- 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c,
- 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53,
- 0x74, 0x61, 0x67, 0x65, 0x52, 0x1b, 0x70, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x57, 0x6f,
- 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x67,
- 0x65, 0x12, 0x5d, 0x0a, 0x19, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x67, 0x65,
- 0x6e, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x15,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41,
- 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x16, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
- 0x67, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
- 0x22, 0x8a, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x74,
- 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61,
- 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x74, 0x65,
- 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x63, 0x68,
- 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x72, 0x6f,
- 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76,
- 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x0e, 0x0a,
- 0x0c, 0x50, 0x61, 0x72, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa3, 0x02,
- 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12,
- 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
- 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x12, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
- 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
- 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
- 0x52, 0x11, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
- 0x6c, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0e, 0x77,
- 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
- 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2e,
- 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74,
- 0x72, 0x79, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67,
- 0x73, 0x1a, 0x40, 0x0a, 0x12, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61,
- 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
- 0x02, 0x38, 0x01, 0x22, 0xbe, 0x03, 0x0a, 0x0b, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65,
- 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70,
- 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18,
- 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
- 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61,
- 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76,
- 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73,
- 0x12, 0x59, 0x0a, 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74,
- 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
- 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76,
- 0x69, 0x64, 0x65, 0x72, 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75,
- 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x5b, 0x0a, 0x19, 0x70,
- 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
- 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f,
- 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63,
- 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
- 0x17, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
- 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x6d, 0x69, 0x74,
- 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6f, 0x6d, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46,
- 0x69, 0x6c, 0x65, 0x73, 0x22, 0xbf, 0x04, 0x0a, 0x0c, 0x50, 0x6c, 0x61, 0x6e, 0x43, 0x6f, 0x6d,
- 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, 0x72,
- 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15,
- 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73,
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
- 0x12, 0x3a, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
- 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x61, 0x0a, 0x17,
- 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72,
- 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e,
- 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65,
- 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
- 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e,
- 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12,
- 0x2d, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54,
- 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x2d,
- 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f,
- 0x64, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2d, 0x0a,
- 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13,
- 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x65,
- 0x73, 0x65, 0x74, 0x52, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04,
- 0x70, 0x6c, 0x61, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x6c, 0x61, 0x6e,
- 0x12, 0x55, 0x0a, 0x15, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x70,
- 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65,
- 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e,
- 0x74, 0x52, 0x14, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61,
- 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x75, 0x6c,
- 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6d,
- 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x6f,
- 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18,
- 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c,
- 0x65, 0x73, 0x48, 0x61, 0x73, 0x68, 0x22, 0x41, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52,
+ 0x6b, 0x65, 0x6e, 0x22, 0x22, 0x0a, 0x10, 0x41, 0x49, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x69, 0x64,
+ 0x65, 0x62, 0x61, 0x72, 0x41, 0x70, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x58, 0x0a, 0x06, 0x41, 0x49, 0x54, 0x61, 0x73,
+ 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
+ 0x64, 0x12, 0x3e, 0x0a, 0x0b, 0x73, 0x69, 0x64, 0x65, 0x62, 0x61, 0x72, 0x5f, 0x61, 0x70, 0x70,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
+ 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x49, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x69, 0x64, 0x65, 0x62,
+ 0x61, 0x72, 0x41, 0x70, 0x70, 0x52, 0x0a, 0x73, 0x69, 0x64, 0x65, 0x62, 0x61, 0x72, 0x41, 0x70,
+ 0x70, 0x22, 0xca, 0x09, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b,
+ 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x53, 0x0a, 0x14, 0x77,
+ 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
+ 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x6f, 0x72,
+ 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+ 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61,
+ 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70,
+ 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73,
+ 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72,
+ 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
+ 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
+ 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x49,
+ 0x64, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f,
+ 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72,
+ 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
+ 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x65,
+ 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65,
+ 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x21, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x61, 0x63,
+ 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x1d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72,
+ 0x4f, 0x69, 0x64, 0x63, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
+ 0x41, 0x0a, 0x1d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e,
+ 0x65, 0x72, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
+ 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
+ 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69,
+ 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
+ 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
+ 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65,
+ 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18,
+ 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
+ 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x42, 0x0a, 0x1e, 0x77,
+ 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x73,
+ 0x73, 0x68, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0f, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77,
+ 0x6e, 0x65, 0x72, 0x53, 0x73, 0x68, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12,
+ 0x44, 0x0a, 0x1f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e,
+ 0x65, 0x72, 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b,
+ 0x65, 0x79, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70,
+ 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x53, 0x73, 0x68, 0x50, 0x72, 0x69, 0x76, 0x61,
+ 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c,
+ 0x64, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
+ 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70,
+ 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65,
+ 0x12, 0x4e, 0x0a, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77,
+ 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x62, 0x61, 0x63, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x13,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+ 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x62, 0x61, 0x63, 0x52, 0x6f, 0x6c, 0x65, 0x73,
+ 0x12, 0x6d, 0x0a, 0x1e, 0x70, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x5f, 0x77, 0x6f, 0x72,
+ 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61,
+ 0x67, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
+ 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x57,
+ 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61,
+ 0x67, 0x65, 0x52, 0x1b, 0x70, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x57, 0x6f, 0x72, 0x6b,
+ 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12,
+ 0x5d, 0x0a, 0x19, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74,
+ 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x15, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
+ 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74,
+ 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x16, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x41,
+ 0x67, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x8a,
+ 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x65, 0x6d,
+ 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x63,
+ 0x68, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x74, 0x65, 0x6d, 0x70,
+ 0x6c, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76,
+ 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
+ 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x76, 0x69,
+ 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
+ 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x0e, 0x0a, 0x0c, 0x50,
+ 0x61, 0x72, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa3, 0x02, 0x0a, 0x0d,
+ 0x50, 0x61, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a,
+ 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72,
+ 0x72, 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x12, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f,
+ 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65,
+ 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11,
+ 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
+ 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0e, 0x77, 0x6f, 0x72,
+ 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
+ 0x50, 0x61, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2e, 0x57, 0x6f,
+ 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
+ 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x1a,
+ 0x40, 0x0a, 0x12, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73,
+ 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
+ 0x01, 0x22, 0xbe, 0x03, 0x0a, 0x0b, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
+ 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72,
+ 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
+ 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,
+ 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
+ 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e,
+ 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x59,
+ 0x0a, 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f,
+ 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78,
+ 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
+ 0x65, 0x72, 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68,
+ 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x5b, 0x0a, 0x19, 0x70, 0x72, 0x65,
+ 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70,
+ 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50,
+ 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x17, 0x70,
+ 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x6d, 0x69, 0x74, 0x5f, 0x6d,
+ 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x0f, 0x6f, 0x6d, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c,
+ 0x65, 0x73, 0x22, 0x91, 0x05, 0x0a, 0x0c, 0x50, 0x6c, 0x61, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
+ 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70,
+ 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3a,
+ 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
+ 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a,
+ 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x61, 0x0a, 0x17, 0x65, 0x78,
+ 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72,
+ 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65,
+ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+ 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a,
+ 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13,
+ 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x69, 0x6d,
+ 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x2d, 0x0a, 0x07,
+ 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e,
+ 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75,
+ 0x6c, 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x70,
+ 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70,
+ 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x65,
+ 0x74, 0x52, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6c,
+ 0x61, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x6c, 0x61, 0x6e, 0x12, 0x55,
+ 0x0a, 0x15, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61,
+ 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e,
+ 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52,
+ 0x14, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f,
+ 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6d, 0x6f, 0x64,
+ 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x6f, 0x64, 0x75,
+ 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0c, 0x20,
+ 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73,
+ 0x48, 0x61, 0x73, 0x68, 0x12, 0x20, 0x0a, 0x0c, 0x68, 0x61, 0x73, 0x5f, 0x61, 0x69, 0x5f, 0x74,
+ 0x61, 0x73, 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x68, 0x61, 0x73, 0x41,
+ 0x69, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x61, 0x69, 0x5f, 0x74, 0x61, 0x73,
+ 0x6b, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
+ 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x49, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x07, 0x61,
+ 0x69, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x22, 0x41, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52,
- 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xbe, 0x02, 0x0a, 0x0d, 0x41, 0x70,
+ 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xee, 0x02, 0x0a, 0x0d, 0x41, 0x70,
0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73,
0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74,
0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
@@ -4757,7 +4901,10 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{
0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x74,
0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e,
- 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x06, 0x54,
+ 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x61, 0x69,
+ 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70,
+ 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x49, 0x54, 0x61, 0x73,
+ 0x6b, 0x52, 0x07, 0x61, 0x69, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x06, 0x54,
0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
@@ -4890,7 +5037,7 @@ func file_provisionersdk_proto_provisioner_proto_rawDescGZIP() []byte {
}
var file_provisionersdk_proto_provisioner_proto_enumTypes = make([]protoimpl.EnumInfo, 8)
-var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 49)
+var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 51)
var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{
(ParameterFormType)(0), // 0: provisioner.ParameterFormType
(LogLevel)(0), // 1: provisioner.LogLevel
@@ -4931,25 +5078,27 @@ var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{
(*Module)(nil), // 36: provisioner.Module
(*Role)(nil), // 37: provisioner.Role
(*RunningAgentAuthToken)(nil), // 38: provisioner.RunningAgentAuthToken
- (*Metadata)(nil), // 39: provisioner.Metadata
- (*Config)(nil), // 40: provisioner.Config
- (*ParseRequest)(nil), // 41: provisioner.ParseRequest
- (*ParseComplete)(nil), // 42: provisioner.ParseComplete
- (*PlanRequest)(nil), // 43: provisioner.PlanRequest
- (*PlanComplete)(nil), // 44: provisioner.PlanComplete
- (*ApplyRequest)(nil), // 45: provisioner.ApplyRequest
- (*ApplyComplete)(nil), // 46: provisioner.ApplyComplete
- (*Timing)(nil), // 47: provisioner.Timing
- (*CancelRequest)(nil), // 48: provisioner.CancelRequest
- (*Request)(nil), // 49: provisioner.Request
- (*Response)(nil), // 50: provisioner.Response
- (*DataUpload)(nil), // 51: provisioner.DataUpload
- (*ChunkPiece)(nil), // 52: provisioner.ChunkPiece
- (*Agent_Metadata)(nil), // 53: provisioner.Agent.Metadata
- nil, // 54: provisioner.Agent.EnvEntry
- (*Resource_Metadata)(nil), // 55: provisioner.Resource.Metadata
- nil, // 56: provisioner.ParseComplete.WorkspaceTagsEntry
- (*timestamppb.Timestamp)(nil), // 57: google.protobuf.Timestamp
+ (*AITaskSidebarApp)(nil), // 39: provisioner.AITaskSidebarApp
+ (*AITask)(nil), // 40: provisioner.AITask
+ (*Metadata)(nil), // 41: provisioner.Metadata
+ (*Config)(nil), // 42: provisioner.Config
+ (*ParseRequest)(nil), // 43: provisioner.ParseRequest
+ (*ParseComplete)(nil), // 44: provisioner.ParseComplete
+ (*PlanRequest)(nil), // 45: provisioner.PlanRequest
+ (*PlanComplete)(nil), // 46: provisioner.PlanComplete
+ (*ApplyRequest)(nil), // 47: provisioner.ApplyRequest
+ (*ApplyComplete)(nil), // 48: provisioner.ApplyComplete
+ (*Timing)(nil), // 49: provisioner.Timing
+ (*CancelRequest)(nil), // 50: provisioner.CancelRequest
+ (*Request)(nil), // 51: provisioner.Request
+ (*Response)(nil), // 52: provisioner.Response
+ (*DataUpload)(nil), // 53: provisioner.DataUpload
+ (*ChunkPiece)(nil), // 54: provisioner.ChunkPiece
+ (*Agent_Metadata)(nil), // 55: provisioner.Agent.Metadata
+ nil, // 56: provisioner.Agent.EnvEntry
+ (*Resource_Metadata)(nil), // 57: provisioner.Resource.Metadata
+ nil, // 58: provisioner.ParseComplete.WorkspaceTagsEntry
+ (*timestamppb.Timestamp)(nil), // 59: google.protobuf.Timestamp
}
var file_provisionersdk_proto_provisioner_proto_depIdxs = []int32{
10, // 0: provisioner.RichParameter.options:type_name -> provisioner.RichParameterOption
@@ -4960,9 +5109,9 @@ var file_provisionersdk_proto_provisioner_proto_depIdxs = []int32{
18, // 5: provisioner.Preset.parameters:type_name -> provisioner.PresetParameter
16, // 6: provisioner.Preset.prebuild:type_name -> provisioner.Prebuild
1, // 7: provisioner.Log.level:type_name -> provisioner.LogLevel
- 54, // 8: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry
+ 56, // 8: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry
33, // 9: provisioner.Agent.apps:type_name -> provisioner.App
- 53, // 10: provisioner.Agent.metadata:type_name -> provisioner.Agent.Metadata
+ 55, // 10: provisioner.Agent.metadata:type_name -> provisioner.Agent.Metadata
29, // 11: provisioner.Agent.display_apps:type_name -> provisioner.DisplayApps
31, // 12: provisioner.Agent.scripts:type_name -> provisioner.Script
30, // 13: provisioner.Agent.extra_envs:type_name -> provisioner.Env
@@ -4974,52 +5123,55 @@ var file_provisionersdk_proto_provisioner_proto_depIdxs = []int32{
2, // 19: provisioner.App.sharing_level:type_name -> provisioner.AppSharingLevel
3, // 20: provisioner.App.open_in:type_name -> provisioner.AppOpenIn
25, // 21: provisioner.Resource.agents:type_name -> provisioner.Agent
- 55, // 22: provisioner.Resource.metadata:type_name -> provisioner.Resource.Metadata
- 4, // 23: provisioner.Metadata.workspace_transition:type_name -> provisioner.WorkspaceTransition
- 37, // 24: provisioner.Metadata.workspace_owner_rbac_roles:type_name -> provisioner.Role
- 5, // 25: provisioner.Metadata.prebuilt_workspace_build_stage:type_name -> provisioner.PrebuiltWorkspaceBuildStage
- 38, // 26: provisioner.Metadata.running_agent_auth_tokens:type_name -> provisioner.RunningAgentAuthToken
- 9, // 27: provisioner.ParseComplete.template_variables:type_name -> provisioner.TemplateVariable
- 56, // 28: provisioner.ParseComplete.workspace_tags:type_name -> provisioner.ParseComplete.WorkspaceTagsEntry
- 39, // 29: provisioner.PlanRequest.metadata:type_name -> provisioner.Metadata
- 12, // 30: provisioner.PlanRequest.rich_parameter_values:type_name -> provisioner.RichParameterValue
- 20, // 31: provisioner.PlanRequest.variable_values:type_name -> provisioner.VariableValue
- 24, // 32: provisioner.PlanRequest.external_auth_providers:type_name -> provisioner.ExternalAuthProvider
- 12, // 33: provisioner.PlanRequest.previous_parameter_values:type_name -> provisioner.RichParameterValue
- 35, // 34: provisioner.PlanComplete.resources:type_name -> provisioner.Resource
- 11, // 35: provisioner.PlanComplete.parameters:type_name -> provisioner.RichParameter
- 23, // 36: provisioner.PlanComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource
- 47, // 37: provisioner.PlanComplete.timings:type_name -> provisioner.Timing
- 36, // 38: provisioner.PlanComplete.modules:type_name -> provisioner.Module
- 17, // 39: provisioner.PlanComplete.presets:type_name -> provisioner.Preset
- 19, // 40: provisioner.PlanComplete.resource_replacements:type_name -> provisioner.ResourceReplacement
- 39, // 41: provisioner.ApplyRequest.metadata:type_name -> provisioner.Metadata
- 35, // 42: provisioner.ApplyComplete.resources:type_name -> provisioner.Resource
- 11, // 43: provisioner.ApplyComplete.parameters:type_name -> provisioner.RichParameter
- 23, // 44: provisioner.ApplyComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource
- 47, // 45: provisioner.ApplyComplete.timings:type_name -> provisioner.Timing
- 57, // 46: provisioner.Timing.start:type_name -> google.protobuf.Timestamp
- 57, // 47: provisioner.Timing.end:type_name -> google.protobuf.Timestamp
- 6, // 48: provisioner.Timing.state:type_name -> provisioner.TimingState
- 40, // 49: provisioner.Request.config:type_name -> provisioner.Config
- 41, // 50: provisioner.Request.parse:type_name -> provisioner.ParseRequest
- 43, // 51: provisioner.Request.plan:type_name -> provisioner.PlanRequest
- 45, // 52: provisioner.Request.apply:type_name -> provisioner.ApplyRequest
- 48, // 53: provisioner.Request.cancel:type_name -> provisioner.CancelRequest
- 21, // 54: provisioner.Response.log:type_name -> provisioner.Log
- 42, // 55: provisioner.Response.parse:type_name -> provisioner.ParseComplete
- 44, // 56: provisioner.Response.plan:type_name -> provisioner.PlanComplete
- 46, // 57: provisioner.Response.apply:type_name -> provisioner.ApplyComplete
- 51, // 58: provisioner.Response.data_upload:type_name -> provisioner.DataUpload
- 52, // 59: provisioner.Response.chunk_piece:type_name -> provisioner.ChunkPiece
- 7, // 60: provisioner.DataUpload.upload_type:type_name -> provisioner.DataUploadType
- 49, // 61: provisioner.Provisioner.Session:input_type -> provisioner.Request
- 50, // 62: provisioner.Provisioner.Session:output_type -> provisioner.Response
- 62, // [62:63] is the sub-list for method output_type
- 61, // [61:62] is the sub-list for method input_type
- 61, // [61:61] is the sub-list for extension type_name
- 61, // [61:61] is the sub-list for extension extendee
- 0, // [0:61] is the sub-list for field type_name
+ 57, // 22: provisioner.Resource.metadata:type_name -> provisioner.Resource.Metadata
+ 39, // 23: provisioner.AITask.sidebar_app:type_name -> provisioner.AITaskSidebarApp
+ 4, // 24: provisioner.Metadata.workspace_transition:type_name -> provisioner.WorkspaceTransition
+ 37, // 25: provisioner.Metadata.workspace_owner_rbac_roles:type_name -> provisioner.Role
+ 5, // 26: provisioner.Metadata.prebuilt_workspace_build_stage:type_name -> provisioner.PrebuiltWorkspaceBuildStage
+ 38, // 27: provisioner.Metadata.running_agent_auth_tokens:type_name -> provisioner.RunningAgentAuthToken
+ 9, // 28: provisioner.ParseComplete.template_variables:type_name -> provisioner.TemplateVariable
+ 58, // 29: provisioner.ParseComplete.workspace_tags:type_name -> provisioner.ParseComplete.WorkspaceTagsEntry
+ 41, // 30: provisioner.PlanRequest.metadata:type_name -> provisioner.Metadata
+ 12, // 31: provisioner.PlanRequest.rich_parameter_values:type_name -> provisioner.RichParameterValue
+ 20, // 32: provisioner.PlanRequest.variable_values:type_name -> provisioner.VariableValue
+ 24, // 33: provisioner.PlanRequest.external_auth_providers:type_name -> provisioner.ExternalAuthProvider
+ 12, // 34: provisioner.PlanRequest.previous_parameter_values:type_name -> provisioner.RichParameterValue
+ 35, // 35: provisioner.PlanComplete.resources:type_name -> provisioner.Resource
+ 11, // 36: provisioner.PlanComplete.parameters:type_name -> provisioner.RichParameter
+ 23, // 37: provisioner.PlanComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource
+ 49, // 38: provisioner.PlanComplete.timings:type_name -> provisioner.Timing
+ 36, // 39: provisioner.PlanComplete.modules:type_name -> provisioner.Module
+ 17, // 40: provisioner.PlanComplete.presets:type_name -> provisioner.Preset
+ 19, // 41: provisioner.PlanComplete.resource_replacements:type_name -> provisioner.ResourceReplacement
+ 40, // 42: provisioner.PlanComplete.ai_tasks:type_name -> provisioner.AITask
+ 41, // 43: provisioner.ApplyRequest.metadata:type_name -> provisioner.Metadata
+ 35, // 44: provisioner.ApplyComplete.resources:type_name -> provisioner.Resource
+ 11, // 45: provisioner.ApplyComplete.parameters:type_name -> provisioner.RichParameter
+ 23, // 46: provisioner.ApplyComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource
+ 49, // 47: provisioner.ApplyComplete.timings:type_name -> provisioner.Timing
+ 40, // 48: provisioner.ApplyComplete.ai_tasks:type_name -> provisioner.AITask
+ 59, // 49: provisioner.Timing.start:type_name -> google.protobuf.Timestamp
+ 59, // 50: provisioner.Timing.end:type_name -> google.protobuf.Timestamp
+ 6, // 51: provisioner.Timing.state:type_name -> provisioner.TimingState
+ 42, // 52: provisioner.Request.config:type_name -> provisioner.Config
+ 43, // 53: provisioner.Request.parse:type_name -> provisioner.ParseRequest
+ 45, // 54: provisioner.Request.plan:type_name -> provisioner.PlanRequest
+ 47, // 55: provisioner.Request.apply:type_name -> provisioner.ApplyRequest
+ 50, // 56: provisioner.Request.cancel:type_name -> provisioner.CancelRequest
+ 21, // 57: provisioner.Response.log:type_name -> provisioner.Log
+ 44, // 58: provisioner.Response.parse:type_name -> provisioner.ParseComplete
+ 46, // 59: provisioner.Response.plan:type_name -> provisioner.PlanComplete
+ 48, // 60: provisioner.Response.apply:type_name -> provisioner.ApplyComplete
+ 53, // 61: provisioner.Response.data_upload:type_name -> provisioner.DataUpload
+ 54, // 62: provisioner.Response.chunk_piece:type_name -> provisioner.ChunkPiece
+ 7, // 63: provisioner.DataUpload.upload_type:type_name -> provisioner.DataUploadType
+ 51, // 64: provisioner.Provisioner.Session:input_type -> provisioner.Request
+ 52, // 65: provisioner.Provisioner.Session:output_type -> provisioner.Response
+ 65, // [65:66] is the sub-list for method output_type
+ 64, // [64:65] is the sub-list for method input_type
+ 64, // [64:64] is the sub-list for extension type_name
+ 64, // [64:64] is the sub-list for extension extendee
+ 0, // [0:64] is the sub-list for field type_name
}
func init() { file_provisionersdk_proto_provisioner_proto_init() }
@@ -5401,7 +5553,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Metadata); i {
+ switch v := v.(*AITaskSidebarApp); i {
case 0:
return &v.state
case 1:
@@ -5413,7 +5565,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Config); i {
+ switch v := v.(*AITask); i {
case 0:
return &v.state
case 1:
@@ -5425,7 +5577,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ParseRequest); i {
+ switch v := v.(*Metadata); i {
case 0:
return &v.state
case 1:
@@ -5437,7 +5589,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ParseComplete); i {
+ switch v := v.(*Config); i {
case 0:
return &v.state
case 1:
@@ -5449,7 +5601,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*PlanRequest); i {
+ switch v := v.(*ParseRequest); i {
case 0:
return &v.state
case 1:
@@ -5461,7 +5613,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*PlanComplete); i {
+ switch v := v.(*ParseComplete); i {
case 0:
return &v.state
case 1:
@@ -5473,7 +5625,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ApplyRequest); i {
+ switch v := v.(*PlanRequest); i {
case 0:
return &v.state
case 1:
@@ -5485,7 +5637,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ApplyComplete); i {
+ switch v := v.(*PlanComplete); i {
case 0:
return &v.state
case 1:
@@ -5497,7 +5649,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Timing); i {
+ switch v := v.(*ApplyRequest); i {
case 0:
return &v.state
case 1:
@@ -5509,7 +5661,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*CancelRequest); i {
+ switch v := v.(*ApplyComplete); i {
case 0:
return &v.state
case 1:
@@ -5521,7 +5673,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Request); i {
+ switch v := v.(*Timing); i {
case 0:
return &v.state
case 1:
@@ -5533,7 +5685,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Response); i {
+ switch v := v.(*CancelRequest); i {
case 0:
return &v.state
case 1:
@@ -5545,7 +5697,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DataUpload); i {
+ switch v := v.(*Request); i {
case 0:
return &v.state
case 1:
@@ -5557,7 +5709,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ChunkPiece); i {
+ switch v := v.(*Response); i {
case 0:
return &v.state
case 1:
@@ -5569,7 +5721,19 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Agent_Metadata); i {
+ switch v := v.(*DataUpload); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_provisionersdk_proto_provisioner_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ChunkPiece); i {
case 0:
return &v.state
case 1:
@@ -5581,6 +5745,18 @@ func file_provisionersdk_proto_provisioner_proto_init() {
}
}
file_provisionersdk_proto_provisioner_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Agent_Metadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_provisionersdk_proto_provisioner_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Resource_Metadata); i {
case 0:
return &v.state
@@ -5598,14 +5774,14 @@ func file_provisionersdk_proto_provisioner_proto_init() {
(*Agent_Token)(nil),
(*Agent_InstanceId)(nil),
}
- file_provisionersdk_proto_provisioner_proto_msgTypes[41].OneofWrappers = []interface{}{
+ file_provisionersdk_proto_provisioner_proto_msgTypes[43].OneofWrappers = []interface{}{
(*Request_Config)(nil),
(*Request_Parse)(nil),
(*Request_Plan)(nil),
(*Request_Apply)(nil),
(*Request_Cancel)(nil),
}
- file_provisionersdk_proto_provisioner_proto_msgTypes[42].OneofWrappers = []interface{}{
+ file_provisionersdk_proto_provisioner_proto_msgTypes[44].OneofWrappers = []interface{}{
(*Response_Log)(nil),
(*Response_Parse)(nil),
(*Response_Plan)(nil),
@@ -5619,7 +5795,7 @@ func file_provisionersdk_proto_provisioner_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_provisionersdk_proto_provisioner_proto_rawDesc,
NumEnums: 8,
- NumMessages: 49,
+ NumMessages: 51,
NumExtensions: 0,
NumServices: 1,
},
diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto
index 603a7fea68234..a57983c21ad9b 100644
--- a/provisionersdk/proto/provisioner.proto
+++ b/provisionersdk/proto/provisioner.proto
@@ -326,6 +326,15 @@ enum PrebuiltWorkspaceBuildStage {
CLAIM = 2; // A prebuilt workspace is being claimed.
}
+message AITaskSidebarApp {
+ string id = 1;
+}
+
+message AITask {
+ string id = 1;
+ AITaskSidebarApp sidebar_app = 2;
+}
+
// Metadata is information about a workspace used in the execution of a build
message Metadata {
string coder_url = 1;
@@ -401,6 +410,13 @@ message PlanComplete {
repeated ResourceReplacement resource_replacements = 10;
bytes module_files = 11;
bytes module_files_hash = 12;
+ // Whether a template has any `coder_ai_task` resources defined, even if not planned for creation.
+ // During a template import, a plan is run which may not yield in any `coder_ai_task` resources, but nonetheless we
+ // still need to know that such resources are defined.
+ //
+ // See `hasAITaskResources` in provisioner/terraform/resources.go for more details.
+ bool has_ai_tasks = 13;
+ repeated provisioner.AITask ai_tasks = 14;
}
// ApplyRequest asks the provisioner to apply the changes. Apply MUST be preceded by a successful plan request/response
@@ -417,6 +433,7 @@ message ApplyComplete {
repeated RichParameter parameters = 4;
repeated ExternalAuthProviderResource external_auth_providers = 5;
repeated Timing timings = 6;
+ repeated provisioner.AITask ai_tasks = 7;
}
message Timing {
diff --git a/site/e2e/helpers.ts b/site/e2e/helpers.ts
index 262567b7d7c96..a738899b25f2c 100644
--- a/site/e2e/helpers.ts
+++ b/site/e2e/helpers.ts
@@ -691,6 +691,7 @@ const createTemplateVersionTar = async (
parameters: [],
externalAuthProviders: [],
timings: [],
+ aiTasks: [],
...response.apply,
} as ApplyComplete;
response.apply.resources = response.apply.resources?.map(fillResource);
@@ -713,6 +714,7 @@ const createTemplateVersionTar = async (
plan: emptyPlan,
moduleFiles: new Uint8Array(),
moduleFilesHash: new Uint8Array(),
+ aiTasks: [],
...response.plan,
} as PlanComplete;
response.plan.resources = response.plan.resources?.map(fillResource);
diff --git a/site/e2e/provisionerGenerated.ts b/site/e2e/provisionerGenerated.ts
index 0dde08604e9e9..686dfb7031945 100644
--- a/site/e2e/provisionerGenerated.ts
+++ b/site/e2e/provisionerGenerated.ts
@@ -360,6 +360,15 @@ export interface RunningAgentAuthToken {
token: string;
}
+export interface AITaskSidebarApp {
+ id: string;
+}
+
+export interface AITask {
+ id: string;
+ sidebarApp: AITaskSidebarApp | undefined;
+}
+
/** Metadata is information about a workspace used in the execution of a build */
export interface Metadata {
coderUrl: string;
@@ -442,6 +451,15 @@ export interface PlanComplete {
resourceReplacements: ResourceReplacement[];
moduleFiles: Uint8Array;
moduleFilesHash: Uint8Array;
+ /**
+ * Whether a template has any `coder_ai_task` resources defined, even if not planned for creation.
+ * During a template import, a plan is run which may not yield in any `coder_ai_task` resources, but nonetheless we
+ * still need to know that such resources are defined.
+ *
+ * See `hasAITaskResources` in provisioner/terraform/resources.go for more details.
+ */
+ hasAiTasks: boolean;
+ aiTasks: AITask[];
}
/**
@@ -460,6 +478,7 @@ export interface ApplyComplete {
parameters: RichParameter[];
externalAuthProviders: ExternalAuthProviderResource[];
timings: Timing[];
+ aiTasks: AITask[];
}
export interface Timing {
@@ -1162,6 +1181,27 @@ export const RunningAgentAuthToken = {
},
};
+export const AITaskSidebarApp = {
+ encode(message: AITaskSidebarApp, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
+ if (message.id !== "") {
+ writer.uint32(10).string(message.id);
+ }
+ return writer;
+ },
+};
+
+export const AITask = {
+ encode(message: AITask, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
+ if (message.id !== "") {
+ writer.uint32(10).string(message.id);
+ }
+ if (message.sidebarApp !== undefined) {
+ AITaskSidebarApp.encode(message.sidebarApp, writer.uint32(18).fork()).ldelim();
+ }
+ return writer;
+ },
+};
+
export const Metadata = {
encode(message: Metadata, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.coderUrl !== "") {
@@ -1341,6 +1381,12 @@ export const PlanComplete = {
if (message.moduleFilesHash.length !== 0) {
writer.uint32(98).bytes(message.moduleFilesHash);
}
+ if (message.hasAiTasks === true) {
+ writer.uint32(104).bool(message.hasAiTasks);
+ }
+ for (const v of message.aiTasks) {
+ AITask.encode(v!, writer.uint32(114).fork()).ldelim();
+ }
return writer;
},
};
@@ -1374,6 +1420,9 @@ export const ApplyComplete = {
for (const v of message.timings) {
Timing.encode(v!, writer.uint32(50).fork()).ldelim();
}
+ for (const v of message.aiTasks) {
+ AITask.encode(v!, writer.uint32(58).fork()).ldelim();
+ }
return writer;
},
};