mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: include agent metadata in workspace list responses (#27934)
Closes #27933. Related: #27897 (single-agent GET). Agent metadata is only readable via a per-agent watch stream, so reading it across N workspaces costs N+1 requests. This adds a batch read to the list endpoint: ```text GET /api/v2/workspaces?q=param:"pool=demo" include_agent_metadata:task_status ``` - New `include_agent_metadata` search key, repeatable and key-scoped. It expands the response, it does not filter workspaces. - `GetWorkspaces` aggregates the requested keys as JSON behind a `CASE`: without opt-in the response is unchanged and the subquery never runs. Runs only for the returned page, inside the same authorized query. - Agents in the response gain `metadata` (`[]codersdk.WorkspaceAgentMetadata`, `omitempty`), mapped by the `workspace_agent_id` each element carries. The collection script is omitted; it can be long. - `codersdk.WorkspaceFilter` gains `IncludeAgentMetadata []string`. - No wildcard, no schema change, no migration. --- Authored by Coder Agents on behalf of @Emyrk.
This commit is contained in:
@@ -170,6 +170,11 @@ type WorkspaceAgent struct {
|
||||
DisplayApps []DisplayApp `json:"display_apps"`
|
||||
LogSources []WorkspaceAgentLogSource `json:"log_sources"`
|
||||
Scripts []WorkspaceAgentScript `json:"scripts"`
|
||||
// Metadata is only populated on the workspaces list endpoint when the
|
||||
// request opts in with the include_agent_metadata search key, and it
|
||||
// only carries the requested keys. The description's script is always
|
||||
// empty here: it can be long, and list consumers want values.
|
||||
Metadata []WorkspaceAgentMetadata `json:"metadata,omitempty"`
|
||||
|
||||
// StartupScriptBehavior is a legacy field that is deprecated in favor
|
||||
// of the `coder_script` resource. It's only referenced by old clients.
|
||||
|
||||
@@ -560,6 +560,9 @@ type WorkspaceFilter struct {
|
||||
SharedWithUser string `json:"shared_with_user,omitempty" typescript:"-"`
|
||||
// SharedWithGroup is the group name, group ID, or <org name>/<group name> of the group that the workspace is shared with
|
||||
SharedWithGroup string `json:"shared_with_group,omitempty" typescript:"-"`
|
||||
// IncludeAgentMetadata expands each agent in the response with the
|
||||
// named metadata keys. It does not filter the returned workspaces.
|
||||
IncludeAgentMetadata []string `json:"include_agent_metadata,omitempty" typescript:"-"`
|
||||
// FilterQuery supports a raw filter query string
|
||||
FilterQuery string `json:"q,omitempty"`
|
||||
}
|
||||
@@ -595,6 +598,9 @@ func (f WorkspaceFilter) asRequestOption() RequestOption {
|
||||
if f.SharedWithGroup != "" {
|
||||
params = append(params, fmt.Sprintf("shared_with_group:%q", f.SharedWithGroup))
|
||||
}
|
||||
for _, key := range f.IncludeAgentMetadata {
|
||||
params = append(params, fmt.Sprintf("include_agent_metadata:%q", key))
|
||||
}
|
||||
if f.FilterQuery != "" {
|
||||
// If custom stuff is added, just add it on here.
|
||||
params = append(params, f.FilterQuery)
|
||||
|
||||
Reference in New Issue
Block a user