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:
@@ -120,6 +120,34 @@ type ChatACLEntry struct {
|
||||
Permissions []policy.Action `json:"permissions"`
|
||||
}
|
||||
|
||||
// AgentMetadataAggregate is the agent_metadata jsonb array the
|
||||
// GetWorkspaces query aggregates for the include_agent_metadata
|
||||
// expansion. Elements have WorkspaceAgentMetadatum's JSON shape; each
|
||||
// carries its workspace_agent_id so multi-agent workspaces can map
|
||||
// values onto the right agent. The generated row keeps
|
||||
// json.RawMessage because sqlc overrides cannot target expression
|
||||
// columns; callers Scan the raw value into this type.
|
||||
type AgentMetadataAggregate []WorkspaceAgentMetadatum
|
||||
|
||||
func (a *AgentMetadataAggregate) Scan(src interface{}) error {
|
||||
switch v := src.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case string:
|
||||
return json.Unmarshal([]byte(v), &a)
|
||||
case []byte:
|
||||
return json.Unmarshal(v, &a)
|
||||
case json.RawMessage:
|
||||
return json.Unmarshal(v, &a)
|
||||
}
|
||||
|
||||
return xerrors.Errorf("unexpected type %T", src)
|
||||
}
|
||||
|
||||
func (a AgentMetadataAggregate) Value() (driver.Value, error) {
|
||||
return json.Marshal(a)
|
||||
}
|
||||
|
||||
type WorkspaceACL map[string]WorkspaceACLEntry
|
||||
|
||||
func (t *WorkspaceACL) Scan(src interface{}) error {
|
||||
|
||||
Reference in New Issue
Block a user