|
1 | 1 | package coderd
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "context" |
4 | 5 | "database/sql"
|
5 | 6 | "errors"
|
6 | 7 | "fmt"
|
@@ -190,49 +191,60 @@ func (api *API) tasksCreate(rw http.ResponseWriter, r *http.Request) {
|
190 | 191 | createWorkspace(ctx, aReq, apiKey.UserID, api, owner, createReq, rw, r)
|
191 | 192 | }
|
192 | 193 |
|
193 |
| -// tasksListResponse wraps a list of experimental tasks. |
194 |
| -// |
195 |
| -// Experimental: Response shape is experimental and may change. |
196 |
| -type tasksListResponse struct { |
197 |
| - Tasks []codersdk.Task `json:"tasks"` |
198 |
| - Count int `json:"count"` |
199 |
| -} |
200 |
| - |
201 |
| -func mapTaskStatus(ws codersdk.Workspace) codersdk.TaskStatus { |
202 |
| - switch ws.LatestBuild.Status { |
203 |
| - case codersdk.WorkspaceStatusPending: |
204 |
| - return codersdk.TaskStatusPending |
205 |
| - |
206 |
| - case codersdk.WorkspaceStatusStarting: |
207 |
| - return codersdk.TaskStatusStarting |
| 194 | +// tasksFromWorkspaces converts a slice of API workspaces into tasks, fetching |
| 195 | +// prompts and mapping status/state. |
| 196 | +func (api *API) tasksFromWorkspaces(ctx context.Context, apiWorkspaces []codersdk.Workspace) ([]codersdk.Task, error) { |
| 197 | + // Fetch prompts for each workspace build and map by build ID. |
| 198 | + buildIDs := make([]uuid.UUID, 0, len(apiWorkspaces)) |
| 199 | + for _, ws := range apiWorkspaces { |
| 200 | + buildIDs = append(buildIDs, ws.LatestBuild.ID) |
| 201 | + } |
| 202 | + parameters, err := api.Database.GetWorkspaceBuildParametersByBuildIDs(ctx, buildIDs) |
| 203 | + if err != nil { |
| 204 | + return nil, err |
| 205 | + } |
| 206 | + promptsByBuildID := make(map[uuid.UUID]string, len(parameters)) |
| 207 | + for _, p := range parameters { |
| 208 | + if p.Name == codersdk.AITaskPromptParameterName { |
| 209 | + promptsByBuildID[p.WorkspaceBuildID] = p.Value |
| 210 | + } |
| 211 | + } |
208 | 212 |
|
209 |
| - case codersdk.WorkspaceStatusRunning: |
| 213 | + tasks := make([]codersdk.Task, 0, len(apiWorkspaces)) |
| 214 | + for _, ws := range apiWorkspaces { |
| 215 | + var currentState *codersdk.TaskStateEntry |
210 | 216 | if ws.LatestAppStatus != nil {
|
211 |
| - switch ws.LatestAppStatus.State { |
212 |
| - case codersdk.WorkspaceAppStatusStateWorking: |
213 |
| - return codersdk.TaskStatusWorking |
214 |
| - case codersdk.WorkspaceAppStatusStateIdle: |
215 |
| - return codersdk.TaskStatusIdle |
216 |
| - case codersdk.WorkspaceAppStatusStateComplete: |
217 |
| - return codersdk.TaskStatusCompleted |
218 |
| - case codersdk.WorkspaceAppStatusStateFailure: |
219 |
| - return codersdk.TaskStatusFailed |
| 217 | + currentState = &codersdk.TaskStateEntry{ |
| 218 | + Timestamp: ws.LatestAppStatus.CreatedAt, |
| 219 | + State: codersdk.TaskState(ws.LatestAppStatus.State), |
| 220 | + Message: ws.LatestAppStatus.Message, |
| 221 | + URI: ws.LatestAppStatus.URI, |
220 | 222 | }
|
221 | 223 | }
|
222 |
| - return codersdk.TaskStatusStarting |
223 |
| - |
224 |
| - case codersdk.WorkspaceStatusStopping, codersdk.WorkspaceStatusStopped: |
225 |
| - return codersdk.TaskStatusStopping |
226 |
| - |
227 |
| - case codersdk.WorkspaceStatusDeleting, codersdk.WorkspaceStatusDeleted: |
228 |
| - return codersdk.TaskStatusDeleting |
| 224 | + tasks = append(tasks, codersdk.Task{ |
| 225 | + ID: ws.ID, |
| 226 | + OrganizationID: ws.OrganizationID, |
| 227 | + OwnerID: ws.OwnerID, |
| 228 | + Name: ws.Name, |
| 229 | + TemplateID: ws.TemplateID, |
| 230 | + WorkspaceID: uuid.NullUUID{Valid: true, UUID: ws.ID}, |
| 231 | + CreatedAt: ws.CreatedAt, |
| 232 | + UpdatedAt: ws.UpdatedAt, |
| 233 | + Prompt: promptsByBuildID[ws.LatestBuild.ID], |
| 234 | + Status: ws.LatestBuild.Status, |
| 235 | + CurrentState: currentState, |
| 236 | + }) |
| 237 | + } |
229 | 238 |
|
230 |
| - case codersdk.WorkspaceStatusFailed, codersdk.WorkspaceStatusCanceling, codersdk.WorkspaceStatusCanceled: |
231 |
| - return codersdk.TaskStatusFailed |
| 239 | + return tasks, nil |
| 240 | +} |
232 | 241 |
|
233 |
| - default: |
234 |
| - return codersdk.TaskStatusPending |
235 |
| - } |
| 242 | +// tasksListResponse wraps a list of experimental tasks. |
| 243 | +// |
| 244 | +// Experimental: Response shape is experimental and may change. |
| 245 | +type tasksListResponse struct { |
| 246 | + Tasks []codersdk.Task `json:"tasks"` |
| 247 | + Count int `json:"count"` |
236 | 248 | }
|
237 | 249 |
|
238 | 250 | // tasksList is an experimental endpoint to list AI tasks by mapping
|
@@ -323,41 +335,14 @@ func (api *API) tasksList(rw http.ResponseWriter, r *http.Request) {
|
323 | 335 | return
|
324 | 336 | }
|
325 | 337 |
|
326 |
| - // Fetch prompts for each workspace build and map by build ID. |
327 |
| - buildIDs := make([]uuid.UUID, 0, len(apiWorkspaces)) |
328 |
| - for _, ws := range apiWorkspaces { |
329 |
| - buildIDs = append(buildIDs, ws.LatestBuild.ID) |
330 |
| - } |
331 |
| - parameters, err := api.Database.GetWorkspaceBuildParametersByBuildIDs(ctx, buildIDs) |
| 338 | + tasks, err := api.tasksFromWorkspaces(ctx, apiWorkspaces) |
332 | 339 | if err != nil {
|
333 | 340 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
334 |
| - Message: "Internal error fetching task prompts.", |
| 341 | + Message: "Internal error fetching task prompts and states.", |
335 | 342 | Detail: err.Error(),
|
336 | 343 | })
|
337 | 344 | return
|
338 | 345 | }
|
339 |
| - promptsByBuildID := make(map[uuid.UUID]string, len(parameters)) |
340 |
| - for _, p := range parameters { |
341 |
| - if p.Name == codersdk.AITaskPromptParameterName { |
342 |
| - promptsByBuildID[p.WorkspaceBuildID] = p.Value |
343 |
| - } |
344 |
| - } |
345 |
| - |
346 |
| - tasks := make([]codersdk.Task, 0, len(apiWorkspaces)) |
347 |
| - for _, ws := range apiWorkspaces { |
348 |
| - tasks = append(tasks, codersdk.Task{ |
349 |
| - ID: ws.ID, |
350 |
| - OrganizationID: ws.OrganizationID, |
351 |
| - OwnerID: ws.OwnerID, |
352 |
| - Name: ws.Name, |
353 |
| - TemplateID: ws.TemplateID, |
354 |
| - WorkspaceID: uuid.NullUUID{Valid: true, UUID: ws.ID}, |
355 |
| - Prompt: promptsByBuildID[ws.LatestBuild.ID], |
356 |
| - Status: mapTaskStatus(ws), |
357 |
| - CreatedAt: ws.CreatedAt, |
358 |
| - UpdatedAt: ws.UpdatedAt, |
359 |
| - }) |
360 |
| - } |
361 | 346 |
|
362 | 347 | httpapi.Write(ctx, rw, http.StatusOK, tasksListResponse{
|
363 | 348 | Tasks: tasks,
|
@@ -432,35 +417,14 @@ func (api *API) taskGet(rw http.ResponseWriter, r *http.Request) {
|
432 | 417 | return
|
433 | 418 | }
|
434 | 419 |
|
435 |
| - // Fetch the AI prompt from the build parameters. |
436 |
| - params, err := api.Database.GetWorkspaceBuildParametersByBuildIDs(ctx, []uuid.UUID{ws.LatestBuild.ID}) |
| 420 | + tasks, err := api.tasksFromWorkspaces(ctx, []codersdk.Workspace{ws}) |
437 | 421 | if err != nil {
|
438 | 422 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
439 |
| - Message: "Internal error fetching task prompt.", |
| 423 | + Message: "Internal error fetching task prompt and state.", |
440 | 424 | Detail: err.Error(),
|
441 | 425 | })
|
442 | 426 | return
|
443 | 427 | }
|
444 |
| - prompt := "" |
445 |
| - for _, p := range params { |
446 |
| - if p.Name == codersdk.AITaskPromptParameterName { |
447 |
| - prompt = p.Value |
448 |
| - break |
449 |
| - } |
450 |
| - } |
451 |
| - |
452 |
| - resp := codersdk.Task{ |
453 |
| - ID: ws.ID, |
454 |
| - OrganizationID: ws.OrganizationID, |
455 |
| - OwnerID: ws.OwnerID, |
456 |
| - Name: ws.Name, |
457 |
| - TemplateID: ws.TemplateID, |
458 |
| - WorkspaceID: uuid.NullUUID{Valid: true, UUID: ws.ID}, |
459 |
| - Prompt: prompt, |
460 |
| - Status: mapTaskStatus(ws), |
461 |
| - CreatedAt: ws.CreatedAt, |
462 |
| - UpdatedAt: ws.UpdatedAt, |
463 |
| - } |
464 | 428 |
|
465 |
| - httpapi.Write(ctx, rw, http.StatusOK, resp) |
| 429 | + httpapi.Write(ctx, rw, http.StatusOK, tasks[0]) |
466 | 430 | }
|
0 commit comments