chore(coderd): introduce TaskAppID and deprecate AITaskSidebarAppID (#20336)

As we're moving away from the SidebarAppID nomenclature, this PR
introduces a new `TaskAppID` field to `codersdk.WorkspaceBuild` and
deprecates the `AITaskSidebarAppID` field. They both contain the same
value.
This commit is contained in:
Danielle Maywood
2025-10-24 10:57:32 +01:00
committed by GitHub
parent e8e31dcb2c
commit e60112e54f
12 changed files with 49 additions and 16 deletions
+5 -5
View File
@@ -635,9 +635,9 @@ func (api *API) taskDelete(rw http.ResponseWriter, r *http.Request) {
// @Router /api/experimental/tasks/{user}/{task}/send [post]
//
// EXPERIMENTAL: This endpoint is experimental and not guaranteed to be stable.
// taskSend submits task input to the tasks sidebar app by dialing the agent
// taskSend submits task input to the task app by dialing the agent
// directly over the tailnet. We enforce ApplicationConnect RBAC on the
// workspace and validate the sidebar app health.
// workspace and validate the task app health.
func (api *API) taskSend(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
task := httpmw.TaskParam(r)
@@ -709,7 +709,7 @@ func (api *API) taskSend(rw http.ResponseWriter, r *http.Request) {
//
// EXPERIMENTAL: This endpoint is experimental and not guaranteed to be stable.
// taskLogs reads task output by dialing the agent directly over the tailnet.
// We enforce ApplicationConnect RBAC on the workspace and validate the sidebar app health.
// We enforce ApplicationConnect RBAC on the workspace and validate the task app health.
func (api *API) taskLogs(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
task := httpmw.TaskParam(r)
@@ -767,7 +767,7 @@ func (api *API) taskLogs(rw http.ResponseWriter, r *http.Request) {
//
// - Fetch the task workspace
// - Authorize ApplicationConnect on the workspace
// - Validate the AI task and sidebar app health
// - Validate the AI task and task app health
// - Dial the agent and construct an HTTP client to the apps loopback URL
//
// The provided callback receives the context, an HTTP client that dials via the
@@ -832,7 +832,7 @@ func (api *API) authAndDoWithTaskAppClient(
appURL := app.Url.String
if appURL == "" {
return httperror.NewResponseError(http.StatusInternalServerError, codersdk.Response{
Message: "Task sidebar app URL is not configured.",
Message: "Task app URL is not configured.",
})
}
parsedURL, err := url.Parse(appURL)
+5
View File
@@ -20462,6 +20462,7 @@ const docTemplate = `{
"type": "object",
"properties": {
"ai_task_sidebar_app_id": {
"description": "Deprecated: This field has been replaced with ` + "`" + `TaskAppID` + "`" + `",
"type": "string",
"format": "uuid"
},
@@ -20543,6 +20544,10 @@ const docTemplate = `{
}
]
},
"task_app_id": {
"type": "string",
"format": "uuid"
},
"template_version_id": {
"type": "string",
"format": "uuid"
+5
View File
@@ -18796,6 +18796,7 @@
"type": "object",
"properties": {
"ai_task_sidebar_app_id": {
"description": "Deprecated: This field has been replaced with `TaskAppID`",
"type": "string",
"format": "uuid"
},
@@ -18873,6 +18874,10 @@
}
]
},
"task_app_id": {
"type": "string",
"format": "uuid"
},
"template_version_id": {
"type": "string",
"format": "uuid"
+4 -3
View File
@@ -1181,9 +1181,9 @@ func (api *API) convertWorkspaceBuild(
if build.HasAITask.Valid {
hasAITask = &build.HasAITask.Bool
}
var aiTasksSidebarAppID *uuid.UUID
var taskAppID *uuid.UUID
if build.AITaskSidebarAppID.Valid {
aiTasksSidebarAppID = &build.AITaskSidebarAppID.UUID
taskAppID = &build.AITaskSidebarAppID.UUID
}
var hasExternalAgent *bool
@@ -1218,7 +1218,8 @@ func (api *API) convertWorkspaceBuild(
MatchedProvisioners: &matchedProvisioners,
TemplateVersionPresetID: presetID,
HasAITask: hasAITask,
AITaskSidebarAppID: aiTasksSidebarAppID,
AITaskSidebarAppID: taskAppID,
TaskAppID: taskAppID,
HasExternalAgent: hasExternalAgent,
}, nil
}
+4 -2
View File
@@ -89,8 +89,10 @@ type WorkspaceBuild struct {
MatchedProvisioners *MatchedProvisioners `json:"matched_provisioners,omitempty"`
TemplateVersionPresetID *uuid.UUID `json:"template_version_preset_id" format:"uuid"`
HasAITask *bool `json:"has_ai_task,omitempty"`
AITaskSidebarAppID *uuid.UUID `json:"ai_task_sidebar_app_id,omitempty" format:"uuid"`
HasExternalAgent *bool `json:"has_external_agent,omitempty"`
// Deprecated: This field has been replaced with `TaskAppID`
AITaskSidebarAppID *uuid.UUID `json:"ai_task_sidebar_app_id,omitempty" format:"uuid"`
TaskAppID *uuid.UUID `json:"task_app_id,omitempty" format:"uuid"`
HasExternalAgent *bool `json:"has_external_agent,omitempty"`
}
// WorkspaceResource describes resources used to create a workspace, for instance:
+7 -1
View File
@@ -222,6 +222,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -463,6 +464,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -1195,6 +1197,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -1509,6 +1512,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -1536,7 +1540,7 @@ Status Code **200**
| Name | Type | Required | Restrictions | Description |
|----------------------------------|--------------------------------------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]` | array | false | | |
| `» ai_task_sidebar_app_id` | string(uuid) | false | | |
| `» ai_task_sidebar_app_id` | string(uuid) | false | | Deprecated: This field has been replaced with `TaskAppID` |
| `» build_number` | integer | false | | |
| `» created_at` | string(date-time) | false | | |
| `» daily_cost` | integer | false | | |
@@ -1687,6 +1691,7 @@ Status Code **200**
| `»» type` | string | false | | |
| `»» workspace_transition` | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition) | false | | |
| `» status` | [codersdk.WorkspaceStatus](schemas.md#codersdkworkspacestatus) | false | | |
| `» task_app_id` | string(uuid) | false | | |
| `» template_version_id` | string(uuid) | false | | |
| `» template_version_name` | string | false | | |
| `» template_version_preset_id` | string(uuid) | false | | |
@@ -2008,6 +2013,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
+5 -1
View File
@@ -10074,6 +10074,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -11243,6 +11244,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -11260,7 +11262,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| Name | Type | Required | Restrictions | Description |
|------------------------------|-------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------|
| `ai_task_sidebar_app_id` | string | false | | |
| `ai_task_sidebar_app_id` | string | false | | Deprecated: This field has been replaced with `TaskAppID` |
| `build_number` | integer | false | | |
| `created_at` | string | false | | |
| `daily_cost` | integer | false | | |
@@ -11276,6 +11278,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `reason` | [codersdk.BuildReason](#codersdkbuildreason) | false | | |
| `resources` | array of [codersdk.WorkspaceResource](#codersdkworkspaceresource) | false | | |
| `status` | [codersdk.WorkspaceStatus](#codersdkworkspacestatus) | false | | |
| `task_app_id` | string | false | | |
| `template_version_id` | string | false | | |
| `template_version_name` | string | false | | |
| `template_version_preset_id` | string | false | | |
@@ -12065,6 +12068,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
+6
View File
@@ -277,6 +277,7 @@ of the template will be used.
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -568,6 +569,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -884,6 +886,7 @@ of the template will be used.
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -1161,6 +1164,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -1453,6 +1457,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
@@ -2004,6 +2009,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \
}
],
"status": "pending",
"task_app_id": "ca438251-3e16-4fae-b9ab-dd3c237c3735",
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
"template_version_name": "string",
"template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
+4
View File
@@ -6363,7 +6363,11 @@ export interface WorkspaceBuild {
readonly matched_provisioners?: MatchedProvisioners;
readonly template_version_preset_id: string | null;
readonly has_ai_task?: boolean;
/**
* Deprecated: This field has been replaced with `TaskAppID`
*/
readonly ai_task_sidebar_app_id?: string;
readonly task_app_id?: string;
readonly has_external_agent?: boolean;
}
+1 -1
View File
@@ -34,7 +34,7 @@ export const TaskApps: FC<TaskAppsProps> = ({ task }) => {
// The Chat UI app will be displayed in the sidebar, so we don't want to
// show it as a web app.
(app) =>
app.id !== task.workspace.latest_build.ai_task_sidebar_app_id &&
app.id !== task.workspace.latest_build.task_app_id &&
app.health !== "disabled",
);
const [embeddedApps, externalApps] = splitEmbeddedAndExternalApps(apps);
+2 -2
View File
@@ -190,7 +190,7 @@ export const SidebarAppNotFound: Story = {
...workspace,
latest_build: {
...workspace.latest_build,
ai_task_sidebar_app_id: "non-existent-app-id",
task_app_id: "non-existent-app-id",
},
},
});
@@ -497,7 +497,7 @@ function mockTaskWorkspace(
latest_build: {
...MockWorkspace.latest_build,
has_ai_task: true,
ai_task_sidebar_app_id: sidebarApp.id,
task_app_id: sidebarApp.id,
resources: [
{
...MockWorkspaceResource,
+1 -1
View File
@@ -143,7 +143,7 @@ const TaskPage = () => {
content = <TaskStartingAgent agent={agent} />;
} else {
const chatApp = getTaskApps(task).find(
(app) => app.id === task.workspace.latest_build.ai_task_sidebar_app_id,
(app) => app.id === task.workspace.latest_build.task_app_id,
);
content = (
<PanelGroup autoSaveId="task" direction="horizontal">