Skip to content

Commit 2116327

Browse files
authored
Merge pull request cli#11758 from cli/kw/agent-list-polish
`gh agent list`: Remove repo-scoped session listing
2 parents c02a8d8 + 4a0c32e commit 2116327

8 files changed

Lines changed: 403 additions & 816 deletions

File tree

pkg/cmd/agent-task/capi/client.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ const capiHost = "api.githubcopilot.com"
1515
// CapiClient defines the methods used by the caller. Implementations
1616
// may be replaced with test doubles in unit tests.
1717
type CapiClient interface {
18-
ListSessionsForViewer(ctx context.Context, limit int) ([]*Session, error)
19-
ListSessionsForRepo(ctx context.Context, owner string, repo string, limit int) ([]*Session, error)
18+
ListLatestSessionsForViewer(ctx context.Context, limit int) ([]*Session, error)
2019
CreateJob(ctx context.Context, owner, repo, problemStatement, baseBranch string) (*Job, error)
2120
GetJob(ctx context.Context, owner, repo, jobID string) (*Job, error)
2221
GetSession(ctx context.Context, id string) (*Session, error)

pkg/cmd/agent-task/capi/client_mock.go

Lines changed: 56 additions & 118 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cmd/agent-task/capi/sessions.go

Lines changed: 29 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ type Session struct {
8888
User *api.GitHubUser
8989
}
9090

91-
// ListSessionsForViewer lists all agent sessions for the
91+
// ListLatestSessionsForViewer lists all agent sessions for the
9292
// authenticated user up to limit.
93-
func (c *CAPIClient) ListSessionsForViewer(ctx context.Context, limit int) ([]*Session, error) {
93+
func (c *CAPIClient) ListLatestSessionsForViewer(ctx context.Context, limit int) ([]*Session, error) {
9494
if limit == 0 {
9595
return nil, nil
9696
}
@@ -99,7 +99,8 @@ func (c *CAPIClient) ListSessionsForViewer(ctx context.Context, limit int) ([]*S
9999
pageSize := defaultSessionsPerPage
100100

101101
sessions := make([]session, 0, limit+pageSize)
102-
102+
seenResources := make(map[int64]struct{})
103+
latestSessions := make([]session, 0, limit)
103104
for page := 1; ; page++ {
104105
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody)
105106
if err != nil {
@@ -109,6 +110,7 @@ func (c *CAPIClient) ListSessionsForViewer(ctx context.Context, limit int) ([]*S
109110
q := req.URL.Query()
110111
q.Set("page_size", strconv.Itoa(pageSize))
111112
q.Set("page_number", strconv.Itoa(page))
113+
q.Set("sort", "last_updated_at,desc")
112114
req.URL.RawQuery = q.Encode()
113115

114116
res, err := c.httpClient.Do(req)
@@ -126,81 +128,45 @@ func (c *CAPIClient) ListSessionsForViewer(ctx context.Context, limit int) ([]*S
126128
return nil, fmt.Errorf("failed to decode sessions response: %w", err)
127129
}
128130

129-
sessions = append(sessions, response.Sessions...)
130-
if len(response.Sessions) < pageSize || len(sessions) >= limit {
131-
break
132-
}
133-
}
134-
135-
// Drop any above the limit
136-
if len(sessions) > limit {
137-
sessions = sessions[:limit]
138-
}
139-
140-
result, err := c.hydrateSessionPullRequestsAndUsers(sessions)
141-
if err != nil {
142-
return nil, fmt.Errorf("failed to fetch session resources: %w", err)
143-
}
144-
145-
return result, nil
146-
}
147-
148-
// ListSessionsForRepo lists agent sessions for a specific repository identified by owner/name up to limit.
149-
func (c *CAPIClient) ListSessionsForRepo(ctx context.Context, owner string, repo string, limit int) ([]*Session, error) {
150-
if owner == "" || repo == "" {
151-
return nil, fmt.Errorf("owner and repo are required")
152-
}
131+
// Process only the newly fetched page worth of sessions.
132+
pageSessions := response.Sessions
133+
sessions = append(sessions, pageSessions...)
153134

154-
if limit == 0 {
155-
return nil, nil
156-
}
157-
158-
url := fmt.Sprintf("%s/agents/sessions/nwo/%s/%s", baseCAPIURL, url.PathEscape(owner), url.PathEscape(repo))
159-
pageSize := defaultSessionsPerPage
160-
161-
sessions := make([]session, 0, limit+pageSize)
162-
163-
for page := 1; ; page++ {
164-
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody)
165-
if err != nil {
166-
return nil, err
167-
}
135+
// De-duplicate sessions by resource ID.
136+
// Because the API returns newest first, once we've seen
137+
// a resource ID we can ignore any older sessions for it.
138+
for _, s := range pageSessions {
139+
if _, exists := seenResources[s.ResourceID]; exists {
140+
continue
141+
}
168142

169-
q := req.URL.Query()
170-
q.Set("page_size", strconv.Itoa(pageSize))
171-
q.Set("page_number", strconv.Itoa(page))
172-
req.URL.RawQuery = q.Encode()
143+
// A zero resource ID is a temporary situation before a PR/resource
144+
// is associated with the session. We should not mark such case as seen.
145+
if s.ResourceID != 0 {
146+
seenResources[s.ResourceID] = struct{}{}
147+
}
173148

174-
res, err := c.httpClient.Do(req)
175-
if err != nil {
176-
return nil, err
177-
}
178-
defer res.Body.Close()
179-
if res.StatusCode != http.StatusOK {
180-
return nil, fmt.Errorf("failed to list sessions: %s", res.Status)
181-
}
182-
var response struct {
183-
Sessions []session `json:"sessions"`
184-
}
185-
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
186-
return nil, fmt.Errorf("failed to decode sessions response: %w", err)
149+
latestSessions = append(latestSessions, s)
150+
if len(latestSessions) >= limit {
151+
break
152+
}
187153
}
188154

189-
sessions = append(sessions, response.Sessions...)
190-
if len(response.Sessions) < pageSize || len(sessions) >= limit {
155+
if len(response.Sessions) < pageSize || len(latestSessions) >= limit {
191156
break
192157
}
193158
}
194159

195160
// Drop any above the limit
196-
if len(sessions) > limit {
197-
sessions = sessions[:limit]
161+
if len(latestSessions) > limit {
162+
latestSessions = latestSessions[:limit]
198163
}
199164

200-
result, err := c.hydrateSessionPullRequestsAndUsers(sessions)
165+
result, err := c.hydrateSessionPullRequestsAndUsers(latestSessions)
201166
if err != nil {
202167
return nil, fmt.Errorf("failed to fetch session resources: %w", err)
203168
}
169+
204170
return result, nil
205171
}
206172

0 commit comments

Comments
 (0)