From 23a44d10ac7d11c5ff0d54c3dca41aad5de1985c Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Mon, 6 Oct 2025 13:12:56 -0300 Subject: [PATCH] feat: include latest build id in task responses (#20181) Adding the latest build ID is necessary to locate the logs associated with the tasks in the UI. --- cli/exp_task_status_test.go | 1 + coderd/aitasks.go | 1 + coderd/aitasks_test.go | 2 ++ codersdk/aitasks.go | 1 + site/src/api/typesGenerated.ts | 1 + site/src/testHelpers/entities.ts | 1 + 6 files changed, 7 insertions(+) diff --git a/cli/exp_task_status_test.go b/cli/exp_task_status_test.go index be62a76476..24a0c82b70 100644 --- a/cli/exp_task_status_test.go +++ b/cli/exp_task_status_test.go @@ -193,6 +193,7 @@ STATE CHANGED STATUS HEALTHY STATE MESSAGE "workspace_agent_id": null, "workspace_agent_lifecycle": null, "workspace_agent_health": null, + "latest_build_id": null, "initial_prompt": "", "status": "running", "current_state": { diff --git a/coderd/aitasks.go b/coderd/aitasks.go index 275cfe8556..fa6bc1dbd5 100644 --- a/coderd/aitasks.go +++ b/coderd/aitasks.go @@ -272,6 +272,7 @@ func taskFromWorkspace(ws codersdk.Workspace, initialPrompt string) codersdk.Tas WorkspaceAgentID: taskAgentID, WorkspaceAgentLifecycle: taskAgentLifecycle, WorkspaceAgentHealth: taskAgentHealth, + LatestBuildID: uuid.NullUUID{Valid: true, UUID: ws.LatestBuild.ID}, CreatedAt: ws.CreatedAt, UpdatedAt: ws.UpdatedAt, InitialPrompt: initialPrompt, diff --git a/coderd/aitasks_test.go b/coderd/aitasks_test.go index 6425e06c77..5ec6f49a5f 100644 --- a/coderd/aitasks_test.go +++ b/coderd/aitasks_test.go @@ -270,6 +270,7 @@ func TestTasks(t *testing.T) { assert.Equal(t, wantPrompt, got.InitialPrompt, "task prompt should match the AI Prompt parameter") assert.Equal(t, workspace.Name, got.Name, "task name should map from workspace name") assert.Equal(t, workspace.ID, got.WorkspaceID.UUID, "workspace id should match") + assert.Equal(t, workspace.LatestBuild.ID, got.LatestBuildID.UUID, "latest build id should match") // Status should be populated via app status or workspace status mapping. assert.NotEmpty(t, got.Status, "task status should not be empty") }) @@ -320,6 +321,7 @@ func TestTasks(t *testing.T) { assert.Equal(t, workspace.Name, task.Name, "task name should map from workspace name") assert.Equal(t, wantPrompt, task.InitialPrompt, "task prompt should match the AI Prompt parameter") assert.Equal(t, workspace.ID, task.WorkspaceID.UUID, "workspace id should match") + assert.Equal(t, workspace.LatestBuild.ID, task.LatestBuildID.UUID, "latest build id should match") assert.NotEmpty(t, task.Status, "task status should not be empty") // Stop the workspace diff --git a/codersdk/aitasks.go b/codersdk/aitasks.go index 21efb15b53..e62f65ce95 100644 --- a/codersdk/aitasks.go +++ b/codersdk/aitasks.go @@ -119,6 +119,7 @@ type Task struct { WorkspaceAgentID uuid.NullUUID `json:"workspace_agent_id" format:"uuid" table:"workspace agent id"` WorkspaceAgentLifecycle *WorkspaceAgentLifecycle `json:"workspace_agent_lifecycle" table:"workspace agent lifecycle"` WorkspaceAgentHealth *WorkspaceAgentHealth `json:"workspace_agent_health" table:"workspace agent health"` + LatestBuildID uuid.NullUUID `json:"latest_build_id" format:"uuid" table:"latest build id"` InitialPrompt string `json:"initial_prompt" table:"initial prompt"` Status WorkspaceStatus `json:"status" enums:"pending,starting,running,stopping,stopped,failed,canceling,canceled,deleting,deleted" table:"status"` CurrentState *TaskStateEntry `json:"current_state" table:"cs,recursive_inline"` diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 1e07cf1aa2..da2c6806a2 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -3330,6 +3330,7 @@ export interface Task { readonly workspace_agent_id: string | null; readonly workspace_agent_lifecycle: WorkspaceAgentLifecycle | null; readonly workspace_agent_health: WorkspaceAgentHealth | null; + readonly latest_build_id: string | null; readonly initial_prompt: string; readonly status: WorkspaceStatus; readonly current_state: TaskStateEntry | null; diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 0b8d87f811..d9a73bc163 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -5031,6 +5031,7 @@ export const MockTask: TypesGen.Task = { workspace_agent_id: MockWorkspaceAgent.id, workspace_agent_lifecycle: MockWorkspaceAgent.lifecycle_state, workspace_agent_health: MockWorkspaceAgent.health, + latest_build_id: MockWorkspace.latest_build.id, initial_prompt: "Perform some task", status: "running", current_state: {